Commit 5aeb0dad authored by Hideaki Yoshifuji's avatar Hideaki Yoshifuji

[IPV6] NDISC: Fix space calculation for link-layer address options.

Signed-off-by: default avatarHideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
parent 1274fcd6
...@@ -183,6 +183,11 @@ static int ndisc_addr_option_pad(unsigned short type) ...@@ -183,6 +183,11 @@ static int ndisc_addr_option_pad(unsigned short type)
} }
} }
static inline int ndisc_opt_addr_space(struct net_device *dev)
{
return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
}
static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len, static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
unsigned short addr_type) unsigned short addr_type)
{ {
...@@ -439,7 +444,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, ...@@ -439,7 +444,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
if (inc_opt) { if (inc_opt) {
if (dev->addr_len) if (dev->addr_len)
len += NDISC_OPT_SPACE(dev->addr_len); len += ndisc_opt_addr_space(dev);
else else
inc_opt = 0; inc_opt = 0;
} }
...@@ -532,7 +537,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, ...@@ -532,7 +537,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
send_llinfo = dev->addr_len && !ipv6_addr_any(saddr); send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
if (send_llinfo) if (send_llinfo)
len += NDISC_OPT_SPACE(dev->addr_len); len += ndisc_opt_addr_space(dev);
skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1, &err); 1, &err);
...@@ -608,7 +613,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, ...@@ -608,7 +613,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
len = sizeof(struct icmp6hdr); len = sizeof(struct icmp6hdr);
if (dev->addr_len) if (dev->addr_len)
len += NDISC_OPT_SPACE(dev->addr_len); len += ndisc_opt_addr_space(dev);
skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1, &err); 1, &err);
...@@ -744,7 +749,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) ...@@ -744,7 +749,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1) + lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1) +
ndisc_addr_option_pad(dev->type); ndisc_addr_option_pad(dev->type);
lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) { if (lladdrlen != ndisc_opt_addr_space(dev)) {
ND_PRINTK2(KERN_WARNING ND_PRINTK2(KERN_WARNING
"ICMPv6 NS: invalid link-layer address length\n"); "ICMPv6 NS: invalid link-layer address length\n");
return; return;
...@@ -902,7 +907,7 @@ static void ndisc_recv_na(struct sk_buff *skb) ...@@ -902,7 +907,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1) + lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1) +
ndisc_addr_option_pad(dev->type); ndisc_addr_option_pad(dev->type);
lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) { if (lladdrlen != ndisc_opt_addr_space(dev)) {
ND_PRINTK2(KERN_WARNING ND_PRINTK2(KERN_WARNING
"ICMPv6 NA: invalid link-layer address length\n"); "ICMPv6 NA: invalid link-layer address length\n");
return; return;
...@@ -997,7 +1002,7 @@ static void ndisc_recv_rs(struct sk_buff *skb) ...@@ -997,7 +1002,7 @@ static void ndisc_recv_rs(struct sk_buff *skb)
lladdr = (u8 *)(ndopts.nd_opts_src_lladdr + 1) + lladdr = (u8 *)(ndopts.nd_opts_src_lladdr + 1) +
ndisc_addr_option_pad(skb->dev->type); ndisc_addr_option_pad(skb->dev->type);
lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) if (lladdrlen != ndisc_opt_addr_space(skb->dev))
goto out; goto out;
} }
...@@ -1171,7 +1176,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1171,7 +1176,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1) + lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1) +
ndisc_addr_option_pad(skb->dev->type); ndisc_addr_option_pad(skb->dev->type);
lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) { if (lladdrlen != ndisc_opt_addr_space(skb->dev)) {
ND_PRINTK2(KERN_WARNING ND_PRINTK2(KERN_WARNING
"ICMPv6 RA: invalid link-layer address length\n"); "ICMPv6 RA: invalid link-layer address length\n");
goto out; goto out;
...@@ -1294,7 +1299,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) ...@@ -1294,7 +1299,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1) + lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1) +
ndisc_addr_option_pad(skb->dev->type); ndisc_addr_option_pad(skb->dev->type);
lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) { if (lladdrlen != ndisc_opt_addr_space(skb->dev)) {
ND_PRINTK2(KERN_WARNING ND_PRINTK2(KERN_WARNING
"ICMPv6 Redirect: invalid link-layer address length\n"); "ICMPv6 Redirect: invalid link-layer address length\n");
in6_dev_put(in6_dev); in6_dev_put(in6_dev);
...@@ -1367,7 +1372,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, ...@@ -1367,7 +1372,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
if (dev->addr_len) { if (dev->addr_len) {
if (neigh->nud_state&NUD_VALID) { if (neigh->nud_state&NUD_VALID) {
len += NDISC_OPT_SPACE(dev->addr_len); len += ndisc_opt_addr_space(dev);
} else { } else {
/* If nexthop is not valid, do not redirect! /* If nexthop is not valid, do not redirect!
We will make it later, when will be sure, We will make it later, when will be sure,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment