Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 351359
b: refs/heads/master
c: 5691744
h: refs/heads/master
i:
  351357: 394722a
  351355: 408c1e1
  351351: 59311f6
  351343: 466ce3b
  351327: df5cafb
  351295: 71a52cb
  351231: e0521f9
v: v3
  • Loading branch information
Shan Wei authored and Antonio Quartulli committed Jan 12, 2013
1 parent f185171 commit 69dc762
Show file tree
Hide file tree
Showing 17 changed files with 92 additions and 77 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: dd3332bfcb2223458f553f341d3388cb84040e6a
refs/heads/master: 569174433d3bd96e206a4b5969a4498371c70d16
8 changes: 6 additions & 2 deletions trunk/include/linux/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,19 @@ static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb)
return (struct ipv6hdr *)skb_transport_header(skb);
}

static inline __u8 ipv6_tclass(const struct ipv6hdr *iph)
{
return (ntohl(*(__be32 *)iph) >> 20) & 0xff;
}

/*
This structure contains results of exthdrs parsing
as offsets from skb->nh.
*/

struct inet6_skb_parm {
int iif;
__be16 ra;
__u16 ra;
__u16 hop;
__u16 dst0;
__u16 srcrt;
Expand All @@ -100,7 +105,6 @@ struct inet6_skb_parm {
#define IP6SKB_XFRM_TRANSFORMED 1
#define IP6SKB_FORWARDED 2
#define IP6SKB_REROUTED 4
#define IP6SKB_ROUTERALERT 8
};

#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
Expand Down
26 changes: 1 addition & 25 deletions trunk/include/net/addrconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,31 +150,7 @@ extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
extern bool ipv6_chk_mcast_addr(struct net_device *dev,
const struct in6_addr *group,
const struct in6_addr *src_addr);

/*
* identify MLD packets for MLD filter exceptions
*/
static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
{
struct icmp6hdr *hdr;

if (nexthdr != IPPROTO_ICMPV6 ||
!pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr)))
return false;

hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset);

switch (hdr->icmp6_type) {
case ICMPV6_MGM_QUERY:
case ICMPV6_MGM_REPORT:
case ICMPV6_MGM_REDUCTION:
case ICMPV6_MLD2_REPORT:
return true;
default:
break;
}
return false;
}
extern bool ipv6_is_mld(struct sk_buff *skb, int nexthdr);

extern void addrconf_prefix_rcv(struct net_device *dev,
u8 *opt, int len, bool sllao);
Expand Down
14 changes: 0 additions & 14 deletions trunk/include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -546,20 +546,6 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add

extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt);

/*
* Header manipulation
*/
static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass,
__be32 flowlabel)
{
*(__be32 *)hdr = ntohl(0x60000000 | (tclass << 20)) | flowlabel;
}

static inline __be32 ip6_flowinfo(const struct ipv6hdr *hdr)
{
return *(__be32 *)hdr & IPV6_FLOWINFO_MASK;
}

/*
* Prototypes exported by ipv6
*/
Expand Down
2 changes: 0 additions & 2 deletions trunk/include/uapi/linux/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ struct ipv6_opt_hdr {
#define ipv6_destopt_hdr ipv6_opt_hdr
#define ipv6_hopopt_hdr ipv6_opt_hdr

/* Router Alert option values (RFC2711) */
#define IPV6_OPT_ROUTERALERT_MLD 0x0000 /* MLD(RFC2710) */

/*
* routing header type 0 (used in cmsghdr struct)
Expand Down
4 changes: 1 addition & 3 deletions trunk/net/batman-adv/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,7 @@ static inline bool batadv_has_timed_out(unsigned long timestamp,
static inline void batadv_add_counter(struct batadv_priv *bat_priv, size_t idx,
size_t count)
{
int cpu = get_cpu();
per_cpu_ptr(bat_priv->bat_counters, cpu)[idx] += count;
put_cpu();
this_cpu_add(bat_priv->bat_counters[idx], count);
}

#define batadv_inc_counter(b, i) batadv_add_counter(b, i, 1)
Expand Down
12 changes: 5 additions & 7 deletions trunk/net/ipv6/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include <net/transp_v6.h>
#include <net/ip6_route.h>
#include <net/tcp_states.h>
#include <net/dsfield.h>

#include <linux/errqueue.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -361,7 +360,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
struct ipv6hdr, daddr);
sin->sin6_addr = ip6h->daddr;
if (np->sndflow)
sin->sin6_flowinfo = ip6_flowinfo(ip6h);
sin->sin6_flowinfo = *(__be32 *)ip6h & IPV6_FLOWINFO_MASK;
if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin->sin6_scope_id = IP6CB(skb)->iif;
} else {
Expand Down Expand Up @@ -488,14 +487,13 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
}

if (np->rxopt.bits.rxtclass) {
int tclass = ipv6_get_dsfield(ipv6_hdr(skb));
int tclass = ipv6_tclass(ipv6_hdr(skb));
put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
}

if (np->rxopt.bits.rxflow) {
__be32 flowinfo = ip6_flowinfo((struct ipv6hdr *)nh);
if (flowinfo)
put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
if (np->rxopt.bits.rxflow && (*(__be32 *)nh & IPV6_FLOWINFO_MASK)) {
__be32 flowinfo = *(__be32 *)nh & IPV6_FLOWINFO_MASK;
put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
}

/* HbH is allowed only once */
Expand Down
3 changes: 1 addition & 2 deletions trunk/net/ipv6/exthdrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,7 @@ static bool ipv6_hop_ra(struct sk_buff *skb, int optoff)
const unsigned char *nh = skb_network_header(skb);

if (nh[optoff + 1] == 2) {
IP6CB(skb)->flags |= IP6SKB_ROUTERALERT;
memcpy(&IP6CB(skb)->ra, nh + optoff + 2, sizeof(IP6CB(skb)->ra));
IP6CB(skb)->ra = optoff;
return true;
}
LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
Expand Down
6 changes: 4 additions & 2 deletions trunk/net/ipv6/ip6_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,9 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
* Push down and install the IP header.
*/
ipv6h = ipv6_hdr(skb);
ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), fl6->flowlabel);
*(__be32 *)ipv6h = fl6->flowlabel | htonl(0x60000000);
dsfield = INET_ECN_encapsulate(0, dsfield);
ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
ipv6h->hop_limit = tunnel->parms.hop_limit;
ipv6h->nexthdr = proto;
ipv6h->saddr = fl6->saddr;
Expand Down Expand Up @@ -1238,7 +1240,7 @@ static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,
struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen);
__be16 *p = (__be16 *)(ipv6h+1);

ip6_flow_hdr(ipv6h, 0, t->fl.u.ip6.flowlabel);
*(__be32 *)ipv6h = t->fl.u.ip6.flowlabel | htonl(0x60000000);
ipv6h->hop_limit = t->parms.hop_limit;
ipv6h->nexthdr = NEXTHDR_GRE;
ipv6h->saddr = t->parms.laddr;
Expand Down
26 changes: 21 additions & 5 deletions trunk/net/ipv6/ip6_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ static int ip6_input_finish(struct sk_buff *skb)
if (ipv6_addr_is_multicast(&hdr->daddr) &&
!ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
&hdr->saddr) &&
!ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
!ipv6_is_mld(skb, nexthdr))
goto discard;
}
if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
Expand Down Expand Up @@ -280,16 +280,18 @@ int ip6_mc_input(struct sk_buff *skb)
struct inet6_skb_parm *opt = IP6CB(skb);

/* Check for MLD */
if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) {
if (unlikely(opt->ra)) {
/* Check if this is a mld message */
u8 *ptr = skb_network_header(skb) + opt->ra;
struct icmp6hdr *icmp6;
u8 nexthdr = hdr->nexthdr;
__be16 frag_off;
int offset;

/* Check if the value of Router Alert
* is for MLD (0x0000).
*/
if (opt->ra == htons(IPV6_OPT_ROUTERALERT_MLD)) {
if ((ptr[2] | ptr[3]) == 0) {
deliver = false;

if (!ipv6_ext_hdr(nexthdr)) {
Expand All @@ -301,10 +303,24 @@ int ip6_mc_input(struct sk_buff *skb)
if (offset < 0)
goto out;

if (!ipv6_is_mld(skb, nexthdr, offset))
if (nexthdr != IPPROTO_ICMPV6)
goto out;

deliver = true;
if (!pskb_may_pull(skb, (skb_network_header(skb) +
offset + 1 - skb->data)))
goto out;

icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);

switch (icmp6->icmp6_type) {
case ICMPV6_MGM_QUERY:
case ICMPV6_MGM_REPORT:
case ICMPV6_MGM_REDUCTION:
case ICMPV6_MLD2_REPORT:
deliver = true;
break;
}
goto out;
}
/* unknown RA - process it normally */
}
Expand Down
8 changes: 5 additions & 3 deletions trunk/net/ipv6/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
if (hlimit < 0)
hlimit = ip6_dst_hoplimit(dst);

ip6_flow_hdr(hdr, tclass, fl6->flowlabel);
*(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel;

hdr->payload_len = htons(seg_len);
hdr->nexthdr = proto;
Expand Down Expand Up @@ -267,7 +267,7 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
skb_put(skb, sizeof(struct ipv6hdr));
hdr = ipv6_hdr(skb);

ip6_flow_hdr(hdr, 0, 0);
*(__be32*)hdr = htonl(0x60000000);

hdr->payload_len = htons(len);
hdr->nexthdr = proto;
Expand Down Expand Up @@ -1548,7 +1548,9 @@ int ip6_push_pending_frames(struct sock *sk)
skb_reset_network_header(skb);
hdr = ipv6_hdr(skb);

ip6_flow_hdr(hdr, np->cork.tclass, fl6->flowlabel);
*(__be32*)hdr = fl6->flowlabel |
htonl(0x60000000 | ((int)np->cork.tclass << 20));

hdr->hop_limit = np->cork.hop_limit;
hdr->nexthdr = proto;
hdr->saddr = fl6->saddr;
Expand Down
4 changes: 3 additions & 1 deletion trunk/net/ipv6/ip6_tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,9 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
ipv6h = ipv6_hdr(skb);
ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), fl6->flowlabel);
*(__be32*)ipv6h = fl6->flowlabel | htonl(0x60000000);
dsfield = INET_ECN_encapsulate(0, dsfield);
ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
ipv6h->hop_limit = t->parms.hop_limit;
ipv6h->nexthdr = proto;
ipv6h->saddr = fl6->saddr;
Expand Down
27 changes: 27 additions & 0 deletions trunk/net/ipv6/mcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,33 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
return err;
}

/*
* identify MLD packets for MLD filter exceptions
*/
bool ipv6_is_mld(struct sk_buff *skb, int nexthdr)
{
struct icmp6hdr *pic;

if (nexthdr != IPPROTO_ICMPV6)
return false;

if (!pskb_may_pull(skb, sizeof(struct icmp6hdr)))
return false;

pic = icmp6_hdr(skb);

switch (pic->icmp6_type) {
case ICMPV6_MGM_QUERY:
case ICMPV6_MGM_REPORT:
case ICMPV6_MGM_REDUCTION:
case ICMPV6_MLD2_REPORT:
return true;
default:
break;
}
return false;
}

/*
* check if the interface/address pair is valid
*/
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv6/netfilter/ip6t_REJECT.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
skb_put(nskb, sizeof(struct ipv6hdr));
skb_reset_network_header(nskb);
ip6h = ipv6_hdr(nskb);
ip6_flow_hdr(ip6h, tclass, 0);
*(__be32 *)ip6h = htonl(0x60000000 | (tclass << 20));
ip6h->hop_limit = ip6_dst_hoplimit(dst);
ip6h->nexthdr = IPPROTO_TCP;
ip6h->saddr = oip6h->daddr;
Expand Down
17 changes: 12 additions & 5 deletions trunk/net/ipv6/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,15 @@ static int rt6_info_hash_nhsfn(unsigned int candidate_count,
{
unsigned int val = fl6->flowi6_proto;

val ^= ipv6_addr_hash(&fl6->daddr);
val ^= ipv6_addr_hash(&fl6->saddr);
val ^= (__force u32)fl6->daddr.s6_addr32[0];
val ^= (__force u32)fl6->daddr.s6_addr32[1];
val ^= (__force u32)fl6->daddr.s6_addr32[2];
val ^= (__force u32)fl6->daddr.s6_addr32[3];

val ^= (__force u32)fl6->saddr.s6_addr32[0];
val ^= (__force u32)fl6->saddr.s6_addr32[1];
val ^= (__force u32)fl6->saddr.s6_addr32[2];
val ^= (__force u32)fl6->saddr.s6_addr32[3];

/* Work only if this not encapsulated */
switch (fl6->flowi6_proto) {
Expand Down Expand Up @@ -987,7 +994,7 @@ void ip6_route_input(struct sk_buff *skb)
.flowi6_iif = skb->dev->ifindex,
.daddr = iph->daddr,
.saddr = iph->saddr,
.flowlabel = ip6_flowinfo(iph),
.flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK,
.flowi6_mark = skb->mark,
.flowi6_proto = iph->nexthdr,
};
Expand Down Expand Up @@ -1152,7 +1159,7 @@ void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
fl6.flowi6_flags = 0;
fl6.daddr = iph->daddr;
fl6.saddr = iph->saddr;
fl6.flowlabel = ip6_flowinfo(iph);
fl6.flowlabel = (*(__be32 *) iph) & IPV6_FLOWINFO_MASK;

dst = ip6_route_output(net, NULL, &fl6);
if (!dst->error)
Expand Down Expand Up @@ -1180,7 +1187,7 @@ void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark)
fl6.flowi6_flags = 0;
fl6.daddr = iph->daddr;
fl6.saddr = iph->saddr;
fl6.flowlabel = ip6_flowinfo(iph);
fl6.flowlabel = (*(__be32 *) iph) & IPV6_FLOWINFO_MASK;

dst = ip6_route_output(net, NULL, &fl6);
if (!dst->error)
Expand Down
6 changes: 3 additions & 3 deletions trunk/net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
newnp->opt = NULL;
newnp->mcast_oif = inet6_iif(skb);
newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
newnp->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb));
newnp->rcv_tclass = ipv6_tclass(ipv6_hdr(skb));

/*
* No need to charge this sock to the relevant IPv6 refcnt debug socks count
Expand Down Expand Up @@ -1243,7 +1243,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
newnp->opt = NULL;
newnp->mcast_oif = inet6_iif(skb);
newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
newnp->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb));
newnp->rcv_tclass = ipv6_tclass(ipv6_hdr(skb));

/* Clone native IPv6 options from listening socket (if any)
Expand Down Expand Up @@ -1456,7 +1456,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit;
if (np->rxopt.bits.rxtclass)
np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb));
np->rcv_tclass = ipv6_tclass(ipv6_hdr(skb));
if (ipv6_opt_accepted(sk, opt_skb)) {
skb_set_owner_r(opt_skb, sk);
opt_skb = xchg(&np->pktoptions, opt_skb);
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv6/xfrm6_tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static inline unsigned int xfrm6_tunnel_spi_hash_byaddr(const xfrm_address_t *ad
{
unsigned int h;

h = ipv6_addr_hash((const struct in6_addr *)addr);
h = (__force u32)(addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3]);
h ^= h >> 16;
h ^= h >> 8;
h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1;
Expand Down

0 comments on commit 69dc762

Please sign in to comment.