Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

batman-adv: add UNICAST_4ADDR packet type

The current unicast packet type does not contain the orig source address. This
patches add a new unicast packet (called UNICAST_4ADDR) which provides two new
fields: the originator source address and the subtype (the type of the data
contained in the packet payload). The former is useful to identify the node
which injected the packet into the network and the latter is useful to avoid
creating new unicast packet types in the future: a macro defining a new subtype
will be enough.

Signed-off-by: Antonio Quartulli <ordex@autistici.org>

+194 -26
+2
net/batman-adv/main.c
··· 300 300 301 301 /* batman icmp packet */ 302 302 batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet; 303 + /* unicast with 4 addresses packet */ 304 + batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet; 303 305 /* unicast packet */ 304 306 batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet; 305 307 /* fragmented unicast packet */
+33 -8
net/batman-adv/packet.h
··· 23 23 #define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ 24 24 25 25 enum batadv_packettype { 26 - BATADV_IV_OGM = 0x01, 27 - BATADV_ICMP = 0x02, 28 - BATADV_UNICAST = 0x03, 29 - BATADV_BCAST = 0x04, 30 - BATADV_VIS = 0x05, 31 - BATADV_UNICAST_FRAG = 0x06, 32 - BATADV_TT_QUERY = 0x07, 33 - BATADV_ROAM_ADV = 0x08, 26 + BATADV_IV_OGM = 0x01, 27 + BATADV_ICMP = 0x02, 28 + BATADV_UNICAST = 0x03, 29 + BATADV_BCAST = 0x04, 30 + BATADV_VIS = 0x05, 31 + BATADV_UNICAST_FRAG = 0x06, 32 + BATADV_TT_QUERY = 0x07, 33 + BATADV_ROAM_ADV = 0x08, 34 + BATADV_UNICAST_4ADDR = 0x09, 35 + }; 36 + 37 + /** 38 + * enum batadv_subtype - packet subtype for unicast4addr 39 + * @BATADV_P_DATA: user payload 40 + */ 41 + enum batadv_subtype { 42 + BATADV_P_DATA = 0x01, 34 43 }; 35 44 36 45 /* this file is included by batctl which needs these defines */ ··· 171 162 struct batadv_header header; 172 163 uint8_t ttvn; /* destination translation table version number */ 173 164 uint8_t dest[ETH_ALEN]; 165 + /* "4 bytes boundary + 2 bytes" long to make the payload after the 166 + * following ethernet header again 4 bytes boundary aligned 167 + */ 168 + }; 169 + 170 + /** 171 + * struct batadv_unicast_4addr_packet - extended unicast packet 172 + * @u: common unicast packet header 173 + * @src: address of the source 174 + * @subtype: packet subtype 175 + */ 176 + struct batadv_unicast_4addr_packet { 177 + struct batadv_unicast_packet u; 178 + uint8_t src[ETH_ALEN]; 179 + uint8_t subtype; 180 + uint8_t reserved; 174 181 /* "4 bytes boundary + 2 bytes" long to make the payload after the 175 182 * following ethernet header again 4 bytes boundary aligned 176 183 */
+6 -2
net/batman-adv/routing.c
··· 986 986 struct batadv_unicast_packet *unicast_packet; 987 987 int hdr_size = sizeof(*unicast_packet); 988 988 989 + unicast_packet = (struct batadv_unicast_packet *)skb->data; 990 + 991 + /* the caller function should have already pulled 2 bytes */ 992 + if (unicast_packet->header.packet_type == BATADV_UNICAST_4ADDR) 993 + hdr_size = sizeof(struct batadv_unicast_4addr_packet); 994 + 989 995 if (batadv_check_unicast_packet(skb, hdr_size) < 0) 990 996 return NET_RX_DROP; 991 997 992 998 if (!batadv_check_unicast_ttvn(bat_priv, skb)) 993 999 return NET_RX_DROP; 994 - 995 - unicast_packet = (struct batadv_unicast_packet *)skb->data; 996 1000 997 1001 /* packet for me */ 998 1002 if (batadv_is_my_mac(unicast_packet->dest)) {
+1 -1
net/batman-adv/soft-interface.c
··· 260 260 goto dropped; 261 261 } 262 262 263 - ret = batadv_unicast_send_skb(skb, bat_priv); 263 + ret = batadv_unicast_send_skb(bat_priv, skb); 264 264 if (ret != 0) 265 265 goto dropped_freed; 266 266 }
+121 -14
net/batman-adv/unicast.c
··· 291 291 return ret; 292 292 } 293 293 294 - int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv) 294 + /** 295 + * batadv_unicast_push_and_fill_skb - extends the buffer and initializes the 296 + * common fields for unicast packets 297 + * @skb: packet 298 + * @hdr_size: amount of bytes to push at the beginning of the skb 299 + * @orig_node: the destination node 300 + * 301 + * Returns false if the buffer extension was not possible or true otherwise 302 + */ 303 + static bool batadv_unicast_push_and_fill_skb(struct sk_buff *skb, int hdr_size, 304 + struct batadv_orig_node *orig_node) 305 + { 306 + struct batadv_unicast_packet *unicast_packet; 307 + uint8_t ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); 308 + 309 + if (batadv_skb_head_push(skb, hdr_size) < 0) 310 + return false; 311 + 312 + unicast_packet = (struct batadv_unicast_packet *)skb->data; 313 + unicast_packet->header.version = BATADV_COMPAT_VERSION; 314 + /* batman packet type: unicast */ 315 + unicast_packet->header.packet_type = BATADV_UNICAST; 316 + /* set unicast ttl */ 317 + unicast_packet->header.ttl = BATADV_TTL; 318 + /* copy the destination for faster routing */ 319 + memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); 320 + /* set the destination tt version number */ 321 + unicast_packet->ttvn = ttvn; 322 + 323 + return true; 324 + } 325 + 326 + /** 327 + * batadv_unicast_prepare_skb - encapsulate an skb with a unicast header 328 + * @skb: the skb containing the payload to encapsulate 329 + * @orig_node: the destination node 330 + * 331 + * Returns false if the payload could not be encapsulated or true otherwise 332 + */ 333 + static bool batadv_unicast_prepare_skb(struct sk_buff *skb, 334 + struct batadv_orig_node *orig_node) 335 + { 336 + size_t uni_size = sizeof(struct batadv_unicast_packet); 337 + return batadv_unicast_push_and_fill_skb(skb, uni_size, orig_node); 338 + } 339 + 340 + /** 341 + * batadv_unicast_4addr_prepare_skb - encapsulate an skb with a unicast4addr 342 + * header 343 + * @bat_priv: the bat priv with all the soft interface information 344 + * @skb: the skb containing the payload to encapsulate 345 + * @orig_node: the destination node 346 + * @packet_subtype: the batman 4addr packet subtype to use 347 + * 348 + * Returns false if the payload could not be encapsulated or true otherwise 349 + */ 350 + static bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv, 351 + struct sk_buff *skb, 352 + struct batadv_orig_node *orig, 353 + int packet_subtype) 354 + { 355 + struct batadv_hard_iface *primary_if; 356 + struct batadv_unicast_4addr_packet *unicast_4addr_packet; 357 + bool ret = false; 358 + 359 + primary_if = batadv_primary_if_get_selected(bat_priv); 360 + if (!primary_if) 361 + goto out; 362 + 363 + /* pull the header space and fill the unicast_packet substructure. 364 + * We can do that because the first member of the unicast_4addr_packet 365 + * is of type struct unicast_packet 366 + */ 367 + if (!batadv_unicast_push_and_fill_skb(skb, 368 + sizeof(*unicast_4addr_packet), 369 + orig)) 370 + goto out; 371 + 372 + unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; 373 + unicast_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR; 374 + memcpy(unicast_4addr_packet->src, primary_if->net_dev->dev_addr, 375 + ETH_ALEN); 376 + unicast_4addr_packet->subtype = packet_subtype; 377 + unicast_4addr_packet->reserved = 0; 378 + 379 + ret = true; 380 + out: 381 + if (primary_if) 382 + batadv_hardif_free_ref(primary_if); 383 + return ret; 384 + } 385 + 386 + /** 387 + * batadv_unicast_generic_send_skb - send an skb as unicast 388 + * @bat_priv: the bat priv with all the soft interface information 389 + * @skb: payload to send 390 + * @packet_type: the batman unicast packet type to use 391 + * @packet_subtype: the batman packet subtype. It is ignored if packet_type is 392 + * not BATADV_UNICAT_4ADDR 393 + * 394 + * Returns 1 in case of error or 0 otherwise 395 + */ 396 + int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv, 397 + struct sk_buff *skb, int packet_type, 398 + int packet_subtype) 295 399 { 296 400 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 297 401 struct batadv_unicast_packet *unicast_packet; ··· 428 324 if (!neigh_node) 429 325 goto out; 430 326 431 - if (batadv_skb_head_push(skb, sizeof(*unicast_packet)) < 0) 327 + switch (packet_type) { 328 + case BATADV_UNICAST: 329 + batadv_unicast_prepare_skb(skb, orig_node); 330 + break; 331 + case BATADV_UNICAST_4ADDR: 332 + batadv_unicast_4addr_prepare_skb(bat_priv, skb, orig_node, 333 + packet_subtype); 334 + break; 335 + default: 336 + /* this function supports UNICAST and UNICAST_4ADDR only. It 337 + * should never be invoked with any other packet type 338 + */ 432 339 goto out; 340 + } 433 341 434 342 unicast_packet = (struct batadv_unicast_packet *)skb->data; 435 - 436 - unicast_packet->header.version = BATADV_COMPAT_VERSION; 437 - /* batman packet type: unicast */ 438 - unicast_packet->header.packet_type = BATADV_UNICAST; 439 - /* set unicast ttl */ 440 - unicast_packet->header.ttl = BATADV_TTL; 441 - /* copy the destination for faster routing */ 442 - memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); 443 - /* set the destination tt version number */ 444 - unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); 445 343 446 344 /* inform the destination node that we are still missing a correct route 447 345 * for this client. The destination will receive this packet and will ··· 454 348 unicast_packet->ttvn = unicast_packet->ttvn - 1; 455 349 456 350 dev_mtu = neigh_node->if_incoming->net_dev->mtu; 457 - if (atomic_read(&bat_priv->fragmentation) && 351 + /* fragmentation mechanism only works for UNICAST (now) */ 352 + if (packet_type == BATADV_UNICAST && 353 + atomic_read(&bat_priv->fragmentation) && 458 354 data_len + sizeof(*unicast_packet) > dev_mtu) { 459 355 /* send frag skb decreases ttl */ 460 356 unicast_packet->header.ttl++; ··· 468 360 469 361 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 470 362 ret = 0; 471 - goto out; 472 363 473 364 out: 474 365 if (neigh_node)
+31 -1
net/batman-adv/unicast.h
··· 29 29 struct batadv_priv *bat_priv, 30 30 struct sk_buff **new_skb); 31 31 void batadv_frag_list_free(struct list_head *head); 32 - int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv); 33 32 int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv, 34 33 struct batadv_hard_iface *hard_iface, 35 34 const uint8_t dstaddr[]); 35 + int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv, 36 + struct sk_buff *skb, int packet_type, 37 + int packet_subtype); 38 + 39 + 40 + /** 41 + * batadv_unicast_send_skb - send the skb encapsulated in a unicast packet 42 + * @bat_priv: the bat priv with all the soft interface information 43 + * @skb: the payload to send 44 + */ 45 + static inline int batadv_unicast_send_skb(struct batadv_priv *bat_priv, 46 + struct sk_buff *skb) 47 + { 48 + return batadv_unicast_generic_send_skb(bat_priv, skb, BATADV_UNICAST, 49 + 0); 50 + } 51 + 52 + /** 53 + * batadv_unicast_send_skb - send the skb encapsulated in a unicast4addr packet 54 + * @bat_priv: the bat priv with all the soft interface information 55 + * @skb: the payload to send 56 + * @packet_subtype: the batman 4addr packet subtype to use 57 + */ 58 + static inline int batadv_unicast_4addr_send_skb(struct batadv_priv *bat_priv, 59 + struct sk_buff *skb, 60 + int packet_subtype) 61 + { 62 + return batadv_unicast_generic_send_skb(bat_priv, skb, 63 + BATADV_UNICAST_4ADDR, 64 + packet_subtype); 65 + } 36 66 37 67 static inline int batadv_frag_can_reassemble(const struct sk_buff *skb, int mtu) 38 68 {