1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors: 3 * 4 * Marek Lindner, Simon Wunderlich 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of version 2 of the GNU General Public 8 * License as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include "main.h" 20 21 #include <linux/byteorder/generic.h> 22 #include <linux/etherdevice.h> 23 #include <linux/gfp.h> 24 #include <linux/if_ether.h> 25 #include <linux/kernel.h> 26 #include <linux/kref.h> 27 #include <linux/list.h> 28 #include <linux/lockdep.h> 29 #include <linux/netdevice.h> 30 #include <linux/pkt_sched.h> 31 #include <linux/rculist.h> 32 #include <linux/rcupdate.h> 33 #include <linux/skbuff.h> 34 #include <linux/slab.h> 35 #include <linux/spinlock.h> 36 #include <linux/stddef.h> 37 #include <linux/string.h> 38 #include <linux/types.h> 39 #include <uapi/linux/batadv_packet.h> 40 41 #include "originator.h" 42 #include "send.h" 43 #include "tvlv.h" 44 45 /** 46 * batadv_tvlv_handler_release() - release tvlv handler from lists and queue for 47 * free after rcu grace period 48 * @ref: kref pointer of the tvlv 49 */ 50 static void batadv_tvlv_handler_release(struct kref *ref) 51 { 52 struct batadv_tvlv_handler *tvlv_handler; 53 54 tvlv_handler = container_of(ref, struct batadv_tvlv_handler, refcount); 55 kfree_rcu(tvlv_handler, rcu); 56 } 57 58 /** 59 * batadv_tvlv_handler_put() - decrement the tvlv container refcounter and 60 * possibly release it 61 * @tvlv_handler: the tvlv handler to free 62 */ 63 static void batadv_tvlv_handler_put(struct batadv_tvlv_handler *tvlv_handler) 64 { 65 kref_put(&tvlv_handler->refcount, batadv_tvlv_handler_release); 66 } 67 68 /** 69 * batadv_tvlv_handler_get() - retrieve tvlv handler from the tvlv handler list 70 * based on the provided type and version (both need to match) 71 * @bat_priv: the bat priv with all the soft interface information 72 * @type: tvlv handler type to look for 73 * @version: tvlv handler version to look for 74 * 75 * Return: tvlv handler if found or NULL otherwise. 76 */ 77 static struct batadv_tvlv_handler * 78 batadv_tvlv_handler_get(struct batadv_priv *bat_priv, u8 type, u8 version) 79 { 80 struct batadv_tvlv_handler *tvlv_handler_tmp, *tvlv_handler = NULL; 81 82 rcu_read_lock(); 83 hlist_for_each_entry_rcu(tvlv_handler_tmp, 84 &bat_priv->tvlv.handler_list, list) { 85 if (tvlv_handler_tmp->type != type) 86 continue; 87 88 if (tvlv_handler_tmp->version != version) 89 continue; 90 91 if (!kref_get_unless_zero(&tvlv_handler_tmp->refcount)) 92 continue; 93 94 tvlv_handler = tvlv_handler_tmp; 95 break; 96 } 97 rcu_read_unlock(); 98 99 return tvlv_handler; 100 } 101 102 /** 103 * batadv_tvlv_container_release() - release tvlv from lists and free 104 * @ref: kref pointer of the tvlv 105 */ 106 static void batadv_tvlv_container_release(struct kref *ref) 107 { 108 struct batadv_tvlv_container *tvlv; 109 110 tvlv = container_of(ref, struct batadv_tvlv_container, refcount); 111 kfree(tvlv); 112 } 113 114 /** 115 * batadv_tvlv_container_put() - decrement the tvlv container refcounter and 116 * possibly release it 117 * @tvlv: the tvlv container to free 118 */ 119 static void batadv_tvlv_container_put(struct batadv_tvlv_container *tvlv) 120 { 121 kref_put(&tvlv->refcount, batadv_tvlv_container_release); 122 } 123 124 /** 125 * batadv_tvlv_container_get() - retrieve tvlv container from the tvlv container 126 * list based on the provided type and version (both need to match) 127 * @bat_priv: the bat priv with all the soft interface information 128 * @type: tvlv container type to look for 129 * @version: tvlv container version to look for 130 * 131 * Has to be called with the appropriate locks being acquired 132 * (tvlv.container_list_lock). 133 * 134 * Return: tvlv container if found or NULL otherwise. 135 */ 136 static struct batadv_tvlv_container * 137 batadv_tvlv_container_get(struct batadv_priv *bat_priv, u8 type, u8 version) 138 { 139 struct batadv_tvlv_container *tvlv_tmp, *tvlv = NULL; 140 141 lockdep_assert_held(&bat_priv->tvlv.container_list_lock); 142 143 hlist_for_each_entry(tvlv_tmp, &bat_priv->tvlv.container_list, list) { 144 if (tvlv_tmp->tvlv_hdr.type != type) 145 continue; 146 147 if (tvlv_tmp->tvlv_hdr.version != version) 148 continue; 149 150 kref_get(&tvlv_tmp->refcount); 151 tvlv = tvlv_tmp; 152 break; 153 } 154 155 return tvlv; 156 } 157 158 /** 159 * batadv_tvlv_container_list_size() - calculate the size of the tvlv container 160 * list entries 161 * @bat_priv: the bat priv with all the soft interface information 162 * 163 * Has to be called with the appropriate locks being acquired 164 * (tvlv.container_list_lock). 165 * 166 * Return: size of all currently registered tvlv containers in bytes. 167 */ 168 static u16 batadv_tvlv_container_list_size(struct batadv_priv *bat_priv) 169 { 170 struct batadv_tvlv_container *tvlv; 171 u16 tvlv_len = 0; 172 173 lockdep_assert_held(&bat_priv->tvlv.container_list_lock); 174 175 hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) { 176 tvlv_len += sizeof(struct batadv_tvlv_hdr); 177 tvlv_len += ntohs(tvlv->tvlv_hdr.len); 178 } 179 180 return tvlv_len; 181 } 182 183 /** 184 * batadv_tvlv_container_remove() - remove tvlv container from the tvlv 185 * container list 186 * @bat_priv: the bat priv with all the soft interface information 187 * @tvlv: the to be removed tvlv container 188 * 189 * Has to be called with the appropriate locks being acquired 190 * (tvlv.container_list_lock). 191 */ 192 static void batadv_tvlv_container_remove(struct batadv_priv *bat_priv, 193 struct batadv_tvlv_container *tvlv) 194 { 195 lockdep_assert_held(&bat_priv->tvlv.container_list_lock); 196 197 if (!tvlv) 198 return; 199 200 hlist_del(&tvlv->list); 201 202 /* first call to decrement the counter, second call to free */ 203 batadv_tvlv_container_put(tvlv); 204 batadv_tvlv_container_put(tvlv); 205 } 206 207 /** 208 * batadv_tvlv_container_unregister() - unregister tvlv container based on the 209 * provided type and version (both need to match) 210 * @bat_priv: the bat priv with all the soft interface information 211 * @type: tvlv container type to unregister 212 * @version: tvlv container type to unregister 213 */ 214 void batadv_tvlv_container_unregister(struct batadv_priv *bat_priv, 215 u8 type, u8 version) 216 { 217 struct batadv_tvlv_container *tvlv; 218 219 spin_lock_bh(&bat_priv->tvlv.container_list_lock); 220 tvlv = batadv_tvlv_container_get(bat_priv, type, version); 221 batadv_tvlv_container_remove(bat_priv, tvlv); 222 spin_unlock_bh(&bat_priv->tvlv.container_list_lock); 223 } 224 225 /** 226 * batadv_tvlv_container_register() - register tvlv type, version and content 227 * to be propagated with each (primary interface) OGM 228 * @bat_priv: the bat priv with all the soft interface information 229 * @type: tvlv container type 230 * @version: tvlv container version 231 * @tvlv_value: tvlv container content 232 * @tvlv_value_len: tvlv container content length 233 * 234 * If a container of the same type and version was already registered the new 235 * content is going to replace the old one. 236 */ 237 void batadv_tvlv_container_register(struct batadv_priv *bat_priv, 238 u8 type, u8 version, 239 void *tvlv_value, u16 tvlv_value_len) 240 { 241 struct batadv_tvlv_container *tvlv_old, *tvlv_new; 242 243 if (!tvlv_value) 244 tvlv_value_len = 0; 245 246 tvlv_new = kzalloc(sizeof(*tvlv_new) + tvlv_value_len, GFP_ATOMIC); 247 if (!tvlv_new) 248 return; 249 250 tvlv_new->tvlv_hdr.version = version; 251 tvlv_new->tvlv_hdr.type = type; 252 tvlv_new->tvlv_hdr.len = htons(tvlv_value_len); 253 254 memcpy(tvlv_new + 1, tvlv_value, ntohs(tvlv_new->tvlv_hdr.len)); 255 INIT_HLIST_NODE(&tvlv_new->list); 256 kref_init(&tvlv_new->refcount); 257 258 spin_lock_bh(&bat_priv->tvlv.container_list_lock); 259 tvlv_old = batadv_tvlv_container_get(bat_priv, type, version); 260 batadv_tvlv_container_remove(bat_priv, tvlv_old); 261 262 kref_get(&tvlv_new->refcount); 263 hlist_add_head(&tvlv_new->list, &bat_priv->tvlv.container_list); 264 spin_unlock_bh(&bat_priv->tvlv.container_list_lock); 265 266 /* don't return reference to new tvlv_container */ 267 batadv_tvlv_container_put(tvlv_new); 268 } 269 270 /** 271 * batadv_tvlv_realloc_packet_buff() - reallocate packet buffer to accommodate 272 * requested packet size 273 * @packet_buff: packet buffer 274 * @packet_buff_len: packet buffer size 275 * @min_packet_len: requested packet minimum size 276 * @additional_packet_len: requested additional packet size on top of minimum 277 * size 278 * 279 * Return: true of the packet buffer could be changed to the requested size, 280 * false otherwise. 281 */ 282 static bool batadv_tvlv_realloc_packet_buff(unsigned char **packet_buff, 283 int *packet_buff_len, 284 int min_packet_len, 285 int additional_packet_len) 286 { 287 unsigned char *new_buff; 288 289 new_buff = kmalloc(min_packet_len + additional_packet_len, GFP_ATOMIC); 290 291 /* keep old buffer if kmalloc should fail */ 292 if (!new_buff) 293 return false; 294 295 memcpy(new_buff, *packet_buff, min_packet_len); 296 kfree(*packet_buff); 297 *packet_buff = new_buff; 298 *packet_buff_len = min_packet_len + additional_packet_len; 299 300 return true; 301 } 302 303 /** 304 * batadv_tvlv_container_ogm_append() - append tvlv container content to given 305 * OGM packet buffer 306 * @bat_priv: the bat priv with all the soft interface information 307 * @packet_buff: ogm packet buffer 308 * @packet_buff_len: ogm packet buffer size including ogm header and tvlv 309 * content 310 * @packet_min_len: ogm header size to be preserved for the OGM itself 311 * 312 * The ogm packet might be enlarged or shrunk depending on the current size 313 * and the size of the to-be-appended tvlv containers. 314 * 315 * Return: size of all appended tvlv containers in bytes. 316 */ 317 u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv, 318 unsigned char **packet_buff, 319 int *packet_buff_len, int packet_min_len) 320 { 321 struct batadv_tvlv_container *tvlv; 322 struct batadv_tvlv_hdr *tvlv_hdr; 323 u16 tvlv_value_len; 324 void *tvlv_value; 325 bool ret; 326 327 spin_lock_bh(&bat_priv->tvlv.container_list_lock); 328 tvlv_value_len = batadv_tvlv_container_list_size(bat_priv); 329 330 ret = batadv_tvlv_realloc_packet_buff(packet_buff, packet_buff_len, 331 packet_min_len, tvlv_value_len); 332 333 if (!ret) 334 goto end; 335 336 if (!tvlv_value_len) 337 goto end; 338 339 tvlv_value = (*packet_buff) + packet_min_len; 340 341 hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) { 342 tvlv_hdr = tvlv_value; 343 tvlv_hdr->type = tvlv->tvlv_hdr.type; 344 tvlv_hdr->version = tvlv->tvlv_hdr.version; 345 tvlv_hdr->len = tvlv->tvlv_hdr.len; 346 tvlv_value = tvlv_hdr + 1; 347 memcpy(tvlv_value, tvlv + 1, ntohs(tvlv->tvlv_hdr.len)); 348 tvlv_value = (u8 *)tvlv_value + ntohs(tvlv->tvlv_hdr.len); 349 } 350 351 end: 352 spin_unlock_bh(&bat_priv->tvlv.container_list_lock); 353 return tvlv_value_len; 354 } 355 356 /** 357 * batadv_tvlv_call_handler() - parse the given tvlv buffer to call the 358 * appropriate handlers 359 * @bat_priv: the bat priv with all the soft interface information 360 * @tvlv_handler: tvlv callback function handling the tvlv content 361 * @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet 362 * @orig_node: orig node emitting the ogm packet 363 * @src: source mac address of the unicast packet 364 * @dst: destination mac address of the unicast packet 365 * @tvlv_value: tvlv content 366 * @tvlv_value_len: tvlv content length 367 * 368 * Return: success if handler was not found or the return value of the handler 369 * callback. 370 */ 371 static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv, 372 struct batadv_tvlv_handler *tvlv_handler, 373 bool ogm_source, 374 struct batadv_orig_node *orig_node, 375 u8 *src, u8 *dst, 376 void *tvlv_value, u16 tvlv_value_len) 377 { 378 if (!tvlv_handler) 379 return NET_RX_SUCCESS; 380 381 if (ogm_source) { 382 if (!tvlv_handler->ogm_handler) 383 return NET_RX_SUCCESS; 384 385 if (!orig_node) 386 return NET_RX_SUCCESS; 387 388 tvlv_handler->ogm_handler(bat_priv, orig_node, 389 BATADV_NO_FLAGS, 390 tvlv_value, tvlv_value_len); 391 tvlv_handler->flags |= BATADV_TVLV_HANDLER_OGM_CALLED; 392 } else { 393 if (!src) 394 return NET_RX_SUCCESS; 395 396 if (!dst) 397 return NET_RX_SUCCESS; 398 399 if (!tvlv_handler->unicast_handler) 400 return NET_RX_SUCCESS; 401 402 return tvlv_handler->unicast_handler(bat_priv, src, 403 dst, tvlv_value, 404 tvlv_value_len); 405 } 406 407 return NET_RX_SUCCESS; 408 } 409 410 /** 411 * batadv_tvlv_containers_process() - parse the given tvlv buffer to call the 412 * appropriate handlers 413 * @bat_priv: the bat priv with all the soft interface information 414 * @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet 415 * @orig_node: orig node emitting the ogm packet 416 * @src: source mac address of the unicast packet 417 * @dst: destination mac address of the unicast packet 418 * @tvlv_value: tvlv content 419 * @tvlv_value_len: tvlv content length 420 * 421 * Return: success when processing an OGM or the return value of all called 422 * handler callbacks. 423 */ 424 int batadv_tvlv_containers_process(struct batadv_priv *bat_priv, 425 bool ogm_source, 426 struct batadv_orig_node *orig_node, 427 u8 *src, u8 *dst, 428 void *tvlv_value, u16 tvlv_value_len) 429 { 430 struct batadv_tvlv_handler *tvlv_handler; 431 struct batadv_tvlv_hdr *tvlv_hdr; 432 u16 tvlv_value_cont_len; 433 u8 cifnotfound = BATADV_TVLV_HANDLER_OGM_CIFNOTFND; 434 int ret = NET_RX_SUCCESS; 435 436 while (tvlv_value_len >= sizeof(*tvlv_hdr)) { 437 tvlv_hdr = tvlv_value; 438 tvlv_value_cont_len = ntohs(tvlv_hdr->len); 439 tvlv_value = tvlv_hdr + 1; 440 tvlv_value_len -= sizeof(*tvlv_hdr); 441 442 if (tvlv_value_cont_len > tvlv_value_len) 443 break; 444 445 tvlv_handler = batadv_tvlv_handler_get(bat_priv, 446 tvlv_hdr->type, 447 tvlv_hdr->version); 448 449 ret |= batadv_tvlv_call_handler(bat_priv, tvlv_handler, 450 ogm_source, orig_node, 451 src, dst, tvlv_value, 452 tvlv_value_cont_len); 453 if (tvlv_handler) 454 batadv_tvlv_handler_put(tvlv_handler); 455 tvlv_value = (u8 *)tvlv_value + tvlv_value_cont_len; 456 tvlv_value_len -= tvlv_value_cont_len; 457 } 458 459 if (!ogm_source) 460 return ret; 461 462 rcu_read_lock(); 463 hlist_for_each_entry_rcu(tvlv_handler, 464 &bat_priv->tvlv.handler_list, list) { 465 if ((tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) && 466 !(tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CALLED)) 467 tvlv_handler->ogm_handler(bat_priv, orig_node, 468 cifnotfound, NULL, 0); 469 470 tvlv_handler->flags &= ~BATADV_TVLV_HANDLER_OGM_CALLED; 471 } 472 rcu_read_unlock(); 473 474 return NET_RX_SUCCESS; 475 } 476 477 /** 478 * batadv_tvlv_ogm_receive() - process an incoming ogm and call the appropriate 479 * handlers 480 * @bat_priv: the bat priv with all the soft interface information 481 * @batadv_ogm_packet: ogm packet containing the tvlv containers 482 * @orig_node: orig node emitting the ogm packet 483 */ 484 void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv, 485 struct batadv_ogm_packet *batadv_ogm_packet, 486 struct batadv_orig_node *orig_node) 487 { 488 void *tvlv_value; 489 u16 tvlv_value_len; 490 491 if (!batadv_ogm_packet) 492 return; 493 494 tvlv_value_len = ntohs(batadv_ogm_packet->tvlv_len); 495 if (!tvlv_value_len) 496 return; 497 498 tvlv_value = batadv_ogm_packet + 1; 499 500 batadv_tvlv_containers_process(bat_priv, true, orig_node, NULL, NULL, 501 tvlv_value, tvlv_value_len); 502 } 503 504 /** 505 * batadv_tvlv_handler_register() - register tvlv handler based on the provided 506 * type and version (both need to match) for ogm tvlv payload and/or unicast 507 * payload 508 * @bat_priv: the bat priv with all the soft interface information 509 * @optr: ogm tvlv handler callback function. This function receives the orig 510 * node, flags and the tvlv content as argument to process. 511 * @uptr: unicast tvlv handler callback function. This function receives the 512 * source & destination of the unicast packet as well as the tvlv content 513 * to process. 514 * @type: tvlv handler type to be registered 515 * @version: tvlv handler version to be registered 516 * @flags: flags to enable or disable TVLV API behavior 517 */ 518 void batadv_tvlv_handler_register(struct batadv_priv *bat_priv, 519 void (*optr)(struct batadv_priv *bat_priv, 520 struct batadv_orig_node *orig, 521 u8 flags, 522 void *tvlv_value, 523 u16 tvlv_value_len), 524 int (*uptr)(struct batadv_priv *bat_priv, 525 u8 *src, u8 *dst, 526 void *tvlv_value, 527 u16 tvlv_value_len), 528 u8 type, u8 version, u8 flags) 529 { 530 struct batadv_tvlv_handler *tvlv_handler; 531 532 tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version); 533 if (tvlv_handler) { 534 batadv_tvlv_handler_put(tvlv_handler); 535 return; 536 } 537 538 tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC); 539 if (!tvlv_handler) 540 return; 541 542 tvlv_handler->ogm_handler = optr; 543 tvlv_handler->unicast_handler = uptr; 544 tvlv_handler->type = type; 545 tvlv_handler->version = version; 546 tvlv_handler->flags = flags; 547 kref_init(&tvlv_handler->refcount); 548 INIT_HLIST_NODE(&tvlv_handler->list); 549 550 spin_lock_bh(&bat_priv->tvlv.handler_list_lock); 551 kref_get(&tvlv_handler->refcount); 552 hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list); 553 spin_unlock_bh(&bat_priv->tvlv.handler_list_lock); 554 555 /* don't return reference to new tvlv_handler */ 556 batadv_tvlv_handler_put(tvlv_handler); 557 } 558 559 /** 560 * batadv_tvlv_handler_unregister() - unregister tvlv handler based on the 561 * provided type and version (both need to match) 562 * @bat_priv: the bat priv with all the soft interface information 563 * @type: tvlv handler type to be unregistered 564 * @version: tvlv handler version to be unregistered 565 */ 566 void batadv_tvlv_handler_unregister(struct batadv_priv *bat_priv, 567 u8 type, u8 version) 568 { 569 struct batadv_tvlv_handler *tvlv_handler; 570 571 tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version); 572 if (!tvlv_handler) 573 return; 574 575 batadv_tvlv_handler_put(tvlv_handler); 576 spin_lock_bh(&bat_priv->tvlv.handler_list_lock); 577 hlist_del_rcu(&tvlv_handler->list); 578 spin_unlock_bh(&bat_priv->tvlv.handler_list_lock); 579 batadv_tvlv_handler_put(tvlv_handler); 580 } 581 582 /** 583 * batadv_tvlv_unicast_send() - send a unicast packet with tvlv payload to the 584 * specified host 585 * @bat_priv: the bat priv with all the soft interface information 586 * @src: source mac address of the unicast packet 587 * @dst: destination mac address of the unicast packet 588 * @type: tvlv type 589 * @version: tvlv version 590 * @tvlv_value: tvlv content 591 * @tvlv_value_len: tvlv content length 592 */ 593 void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, u8 *src, 594 u8 *dst, u8 type, u8 version, 595 void *tvlv_value, u16 tvlv_value_len) 596 { 597 struct batadv_unicast_tvlv_packet *unicast_tvlv_packet; 598 struct batadv_tvlv_hdr *tvlv_hdr; 599 struct batadv_orig_node *orig_node; 600 struct sk_buff *skb; 601 unsigned char *tvlv_buff; 602 unsigned int tvlv_len; 603 ssize_t hdr_len = sizeof(*unicast_tvlv_packet); 604 605 orig_node = batadv_orig_hash_find(bat_priv, dst); 606 if (!orig_node) 607 return; 608 609 tvlv_len = sizeof(*tvlv_hdr) + tvlv_value_len; 610 611 skb = netdev_alloc_skb_ip_align(NULL, ETH_HLEN + hdr_len + tvlv_len); 612 if (!skb) 613 goto out; 614 615 skb->priority = TC_PRIO_CONTROL; 616 skb_reserve(skb, ETH_HLEN); 617 tvlv_buff = skb_put(skb, sizeof(*unicast_tvlv_packet) + tvlv_len); 618 unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)tvlv_buff; 619 unicast_tvlv_packet->packet_type = BATADV_UNICAST_TVLV; 620 unicast_tvlv_packet->version = BATADV_COMPAT_VERSION; 621 unicast_tvlv_packet->ttl = BATADV_TTL; 622 unicast_tvlv_packet->reserved = 0; 623 unicast_tvlv_packet->tvlv_len = htons(tvlv_len); 624 unicast_tvlv_packet->align = 0; 625 ether_addr_copy(unicast_tvlv_packet->src, src); 626 ether_addr_copy(unicast_tvlv_packet->dst, dst); 627 628 tvlv_buff = (unsigned char *)(unicast_tvlv_packet + 1); 629 tvlv_hdr = (struct batadv_tvlv_hdr *)tvlv_buff; 630 tvlv_hdr->version = version; 631 tvlv_hdr->type = type; 632 tvlv_hdr->len = htons(tvlv_value_len); 633 tvlv_buff += sizeof(*tvlv_hdr); 634 memcpy(tvlv_buff, tvlv_value, tvlv_value_len); 635 636 batadv_send_skb_to_orig(skb, orig_node, NULL); 637 out: 638 batadv_orig_node_put(orig_node); 639 } 640