diff options
Diffstat (limited to 'net/batman-adv')
-rw-r--r-- | net/batman-adv/distributed-arp-table.c | 13 | ||||
-rw-r--r-- | net/batman-adv/main.c | 18 | ||||
-rw-r--r-- | net/batman-adv/network-coding.c | 8 |
3 files changed, 32 insertions, 7 deletions
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 8e15d966d9b0..239992021b1d 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c | |||
@@ -837,6 +837,19 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | |||
837 | 837 | ||
838 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); | 838 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); |
839 | if (dat_entry) { | 839 | if (dat_entry) { |
840 | /* If the ARP request is destined for a local client the local | ||
841 | * client will answer itself. DAT would only generate a | ||
842 | * duplicate packet. | ||
843 | * | ||
844 | * Moreover, if the soft-interface is enslaved into a bridge, an | ||
845 | * additional DAT answer may trigger kernel warnings about | ||
846 | * a packet coming from the wrong port. | ||
847 | */ | ||
848 | if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) { | ||
849 | ret = true; | ||
850 | goto out; | ||
851 | } | ||
852 | |||
840 | skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src, | 853 | skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src, |
841 | bat_priv->soft_iface, ip_dst, hw_src, | 854 | bat_priv->soft_iface, ip_dst, hw_src, |
842 | dat_entry->mac_addr, hw_src); | 855 | dat_entry->mac_addr, hw_src); |
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 3e30a0f1b908..1240f07ad31d 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -163,14 +163,22 @@ void batadv_mesh_free(struct net_device *soft_iface) | |||
163 | batadv_vis_quit(bat_priv); | 163 | batadv_vis_quit(bat_priv); |
164 | 164 | ||
165 | batadv_gw_node_purge(bat_priv); | 165 | batadv_gw_node_purge(bat_priv); |
166 | batadv_originator_free(bat_priv); | ||
167 | batadv_nc_free(bat_priv); | 166 | batadv_nc_free(bat_priv); |
167 | batadv_dat_free(bat_priv); | ||
168 | batadv_bla_free(bat_priv); | ||
168 | 169 | ||
170 | /* Free the TT and the originator tables only after having terminated | ||
171 | * all the other depending components which may use these structures for | ||
172 | * their purposes. | ||
173 | */ | ||
169 | batadv_tt_free(bat_priv); | 174 | batadv_tt_free(bat_priv); |
170 | 175 | ||
171 | batadv_bla_free(bat_priv); | 176 | /* Since the originator table clean up routine is accessing the TT |
172 | 177 | * tables as well, it has to be invoked after the TT tables have been | |
173 | batadv_dat_free(bat_priv); | 178 | * freed and marked as empty. This ensures that no cleanup RCU callbacks |
179 | * accessing the TT data are scheduled for later execution. | ||
180 | */ | ||
181 | batadv_originator_free(bat_priv); | ||
174 | 182 | ||
175 | free_percpu(bat_priv->bat_counters); | 183 | free_percpu(bat_priv->bat_counters); |
176 | 184 | ||
@@ -475,7 +483,7 @@ static int batadv_param_set_ra(const char *val, const struct kernel_param *kp) | |||
475 | char *algo_name = (char *)val; | 483 | char *algo_name = (char *)val; |
476 | size_t name_len = strlen(algo_name); | 484 | size_t name_len = strlen(algo_name); |
477 | 485 | ||
478 | if (algo_name[name_len - 1] == '\n') | 486 | if (name_len > 0 && algo_name[name_len - 1] == '\n') |
479 | algo_name[name_len - 1] = '\0'; | 487 | algo_name[name_len - 1] = '\0'; |
480 | 488 | ||
481 | bat_algo_ops = batadv_algo_get(algo_name); | 489 | bat_algo_ops = batadv_algo_get(algo_name); |
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index f7c54305a918..e84629ece9b7 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c | |||
@@ -1514,6 +1514,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
1514 | struct ethhdr *ethhdr, ethhdr_tmp; | 1514 | struct ethhdr *ethhdr, ethhdr_tmp; |
1515 | uint8_t *orig_dest, ttl, ttvn; | 1515 | uint8_t *orig_dest, ttl, ttvn; |
1516 | unsigned int coding_len; | 1516 | unsigned int coding_len; |
1517 | int err; | ||
1517 | 1518 | ||
1518 | /* Save headers temporarily */ | 1519 | /* Save headers temporarily */ |
1519 | memcpy(&coded_packet_tmp, skb->data, sizeof(coded_packet_tmp)); | 1520 | memcpy(&coded_packet_tmp, skb->data, sizeof(coded_packet_tmp)); |
@@ -1568,8 +1569,11 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
1568 | coding_len); | 1569 | coding_len); |
1569 | 1570 | ||
1570 | /* Resize decoded skb if decoded with larger packet */ | 1571 | /* Resize decoded skb if decoded with larger packet */ |
1571 | if (nc_packet->skb->len > coding_len + h_size) | 1572 | if (nc_packet->skb->len > coding_len + h_size) { |
1572 | pskb_trim_rcsum(skb, coding_len + h_size); | 1573 | err = pskb_trim_rcsum(skb, coding_len + h_size); |
1574 | if (err) | ||
1575 | return NULL; | ||
1576 | } | ||
1573 | 1577 | ||
1574 | /* Create decoded unicast packet */ | 1578 | /* Create decoded unicast packet */ |
1575 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 1579 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |