summaryrefslogtreecommitdiff
path: root/include/net/addrconf.h
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@c0d3.blue>2019-01-21 09:26:25 +0300
committerDavid S. Miller <davem@davemloft.net>2019-01-23 04:18:08 +0300
commitba5ea614622dca6d675b4cc8a97270569ae13a23 (patch)
tree9bcc70bdcaa5cb0b19a1c625c470e70571327d0e /include/net/addrconf.h
parent6679cf099b81994884246612538bd4c7fb935b30 (diff)
downloadlinux-ba5ea614622dca6d675b4cc8a97270569ae13a23.tar.xz
bridge: simplify ip_mc_check_igmp() and ipv6_mc_check_mld() calls
This patch refactors ip_mc_check_igmp(), ipv6_mc_check_mld() and their callers (more precisely, the Linux bridge) to not rely on the skb_trimmed parameter anymore. An skb with its tail trimmed to the IP packet length was initially introduced for the following three reasons: 1) To be able to verify the ICMPv6 checksum. 2) To be able to distinguish the version of an IGMP or MLD query. They are distinguishable only by their size. 3) To avoid parsing data for an IGMPv3 or MLDv2 report that is beyond the IP packet but still within the skb. The first case still uses a cloned and potentially trimmed skb to verfiy. However, there is no need to propagate it to the caller. For the second and third case explicit IP packet length checks were added. This hopefully makes ip_mc_check_igmp() and ipv6_mc_check_mld() easier to read and verfiy, as well as easier to use. Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/addrconf.h')
-rw-r--r--include/net/addrconf.h12
1 files changed, 11 insertions, 1 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 1656c5978498..daf11dcb0f70 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -49,6 +49,7 @@ struct prefix_info {
struct in6_addr prefix;
};
+#include <linux/ipv6.h>
#include <linux/netdevice.h>
#include <net/if_inet6.h>
#include <net/ipv6.h>
@@ -201,6 +202,15 @@ u32 ipv6_addr_label(struct net *net, const struct in6_addr *addr,
/*
* multicast prototypes (mcast.c)
*/
+static inline int ipv6_mc_may_pull(struct sk_buff *skb,
+ unsigned int len)
+{
+ if (skb_transport_offset(skb) + ipv6_transport_len(skb) < len)
+ return -EINVAL;
+
+ return pskb_may_pull(skb, len);
+}
+
int ipv6_sock_mc_join(struct sock *sk, int ifindex,
const struct in6_addr *addr);
int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
@@ -219,7 +229,7 @@ void ipv6_mc_unmap(struct inet6_dev *idev);
void ipv6_mc_remap(struct inet6_dev *idev);
void ipv6_mc_init_dev(struct inet6_dev *idev);
void ipv6_mc_destroy_dev(struct inet6_dev *idev);
-int ipv6_mc_check_mld(struct sk_buff *skb, struct sk_buff **skb_trimmed);
+int ipv6_mc_check_mld(struct sk_buff *skb);
void addrconf_dad_failure(struct sk_buff *skb, struct inet6_ifaddr *ifp);
bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,