From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kunihiro Ishiguro Subject: Re: [PATCH] IPv6 IPsec support Date: Wed, 19 Feb 2003 01:13:51 -0800 Sender: netdev-bounce@oss.sgi.com Message-ID: <87of58hbu8.wl@ipinfusion.com> References: <20030219134850.5f203ea7.Kazunori.Miyazawa@jp.yokogawa.com> <87znos3j8s.wl@ipinfusion.com> <20030218.230211.89243941.davem@redhat.com> Mime-Version: 1.0 (generated by SEMI 1.14.3 - "Ushinoya") Content-Type: text/plain; charset=US-ASCII Cc: Kazunori.Miyazawa@jp.yokogawa.com, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, kuznet@ms2.inr.ac.ru Return-path: To: "David S. Miller" In-Reply-To: <20030218.230211.89243941.davem@redhat.com> Errors-to: netdev-bounce@oss.sgi.com List-Id: netdev.vger.kernel.org >I would ask that Alexey and myself stay on the CC: list. > >It would not hurt to keep netdev as well, perhaps we can >breed some new experts in our ipsec code :-) I believe many ipsec experts on this list ;-). >@@ -428,20 +455,79 @@ > static inline int > xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl) > { >- return !memcmp(fl->fl6_dst, sel->daddr.a6, sizeof(struct in6_addr)) && >- !((fl->uli_u.ports.dport^sel->dport)&sel->dport_mask) && >- !((fl->uli_u.ports.sport^sel->sport)&sel->sport_mask) && >- (fl->proto == sel->proto || !sel->proto) && >- (fl->oif == sel->ifindex || !sel->ifindex) && >- !memcmp(fl->fl6_src, sel->saddr.a6, sizeof(struct in6_addr)); >+ return !memcmp(fl->fl6_dst, &sel->daddr, (sel->prefixlen_d)/8) && >+ !memcmp(fl->fl6_src, &sel->saddr, (sel->prefixlen_s)/8) && >+ !((fl->uli_u.ports.dport^sel->dport)&sel->dport_mask) && >+ !((fl->uli_u.ports.sport^sel->sport)&sel->sport_mask) && >+ (fl->proto == sel->proto || !sel->proto) && >+ (fl->oif == sel->ifindex || !sel->ifindex); > } memcmp with prefixlen/8 is too generous. Orignal non mask comparison is much worser (maybe my code...). We need bit comparison here. Poor xfrm6_selector_match()... I only have below idea... addr_match() is taken from ip6_fib.c... static __inline__ int addr_match(void *token1, void *token2, int prefixlen) { __u32 *a1 = token1; __u32 *a2 = token2; int pdw; int pbi; pdw = prefixlen >> 5; /* num of whole __u32 in prefix */ pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */ if (pdw) if (memcmp(a1, a2, pdw << 2)) return 0; if (pbi) { __u32 mask; mask = htonl((0xffffffff) << (32 - pbi)); if ((a1[pdw] ^ a2[pdw]) & mask) return 0; } return 1; } static inline int xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl) { return addr_match(fl->fl6_dst, &sel->daddr, sel->prefixlen_d) && addr_match(fl->fl6_src, &sel->saddr, sel->prefixlen_s) && !((fl->uli_u.ports.dport^sel->dport)&sel->dport_mask) && !((fl->uli_u.ports.sport^sel->sport)&sel->sport_mask) && (fl->proto == sel->proto || !sel->proto) && (fl->oif == sel->ifindex || !sel->ifindex); }