Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F132557906
D8877.id23178.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D8877.id23178.diff
View Options
Index: sys/netinet/ip_fastfwd.c
===================================================================
--- sys/netinet/ip_fastfwd.c
+++ sys/netinet/ip_fastfwd.c
@@ -154,7 +154,6 @@
struct in_addr odest, dest;
uint16_t ip_len, ip_off;
int error = 0;
- struct m_tag *fwd_tag = NULL;
/*
* Are we active and forwarding packets?
@@ -317,9 +316,8 @@
/*
* Destination address changed?
*/
- if (m->m_flags & M_IP_NEXTHOP)
- fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
- if (odest.s_addr != dest.s_addr || fwd_tag != NULL) {
+ if (odest.s_addr != dest.s_addr ||
+ (IP_HAS_NEXTHOP(m) && !ip_get_fwdtag(m, &dst, NULL))) {
/*
* Is it now for a local address on this host?
*/
@@ -331,15 +329,13 @@
m->m_flags |= M_FASTFWD_OURS;
return (m);
}
+ if (IP_HAS_NEXTHOP(m)) {
+ dest.s_addr = dst.sin_addr.s_addr;
+ ip_flush_fwdtag(m);
+ }
/*
* Redo route lookup with new destination address
*/
- if (fwd_tag) {
- dest.s_addr = ((struct sockaddr_in *)
- (fwd_tag + 1))->sin_addr.s_addr;
- m_tag_delete(m, fwd_tag);
- m->m_flags &= ~M_IP_NEXTHOP;
- }
if (ip_findroute(&nh, dest, m) != 0)
return (NULL); /* icmp unreach already sent */
}
Index: sys/netinet/ip_input.c
===================================================================
--- sys/netinet/ip_input.c
+++ sys/netinet/ip_input.c
@@ -605,16 +605,14 @@
m->m_flags &= ~M_FASTFWD_OURS;
goto ours;
}
- if (m->m_flags & M_IP_NEXTHOP) {
- if (m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL) {
- /*
- * Directly ship the packet on. This allows
- * forwarding packets originally destined to us
- * to some other directly connected host.
- */
- ip_forward(m, 1);
- return;
- }
+ if (IP_HAS_NEXTHOP(m)) {
+ /*
+ * Directly ship the packet on. This allows
+ * forwarding packets originally destined to us
+ * to some other directly connected host.
+ */
+ ip_forward(m, 1);
+ return;
}
passin:
Index: sys/netinet/ip_output.c
===================================================================
--- sys/netinet/ip_output.c
+++ sys/netinet/ip_output.c
@@ -108,7 +108,6 @@
ip_output_pfil(struct mbuf **mp, struct ifnet *ifp, struct inpcb *inp,
struct sockaddr_in *dst, int *fibnum, int *error)
{
- struct m_tag *fwd_tag = NULL;
struct mbuf *m;
struct in_addr odst;
struct ip *ip;
@@ -182,13 +181,9 @@
return 1; /* Finished */
}
/* Or forward to some other address? */
- if ((m->m_flags & M_IP_NEXTHOP) &&
- ((fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL)) {
- bcopy((fwd_tag+1), dst, sizeof(struct sockaddr_in));
+ if (IP_HAS_NEXTHOP(m) && !ip_get_fwdtag(m, dst, NULL)) {
m->m_flags |= M_SKIP_FIREWALL;
- m->m_flags &= ~M_IP_NEXTHOP;
- m_tag_delete(m, fwd_tag);
-
+ ip_flush_fwdtag(m);
return -1; /* Reloop for CHANGE of dst */
}
@@ -1415,3 +1410,82 @@
if_simloop(ifp, copym, AF_INET, 0);
}
}
+
+int
+ip_set_fwdtag(struct mbuf *m, struct sockaddr_in *dst, u_short ifidx)
+{
+ struct sockaddr_in *sa;
+ struct m_tag *fwd_tag;
+
+ (void)ifidx; /* XXX: store after dst, or make struct? */
+
+ KASSERT(dst != NULL, ("%s: !dst", __func__));
+ KASSERT(dst->sa_family == AF_INET, ("%s: !AF_INET", __func__));
+
+ fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+ if (fwd_tag != NULL) {
+ KASSERT(((struct sockaddr *)(fwd_tag+1))->sa_family ==
+ AF_INET, ("%s: !AF_INET", __func__));
+
+ m_tag_unlink(m, fwd_tag);
+ } else {
+ fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD, sizeof(*dst),
+ M_NOWAIT);
+ if (fwd_tag == NULL) {
+ return (ENOBUFS);
+ }
+ }
+
+ sa = (struct sockaddr_in *)(fwd_tag+1);
+
+ bcopy(dst, sa, sizeof(*dst));
+ m->m_flags |= M_IP_NEXTHOP;
+
+ if (in_localip(sa->sin_addr))
+ m->m_flags |= M_FASTFWD_OURS;
+ else
+ m->m_flags &= ~M_FASTFWD_OURS;
+
+ m_tag_prepend(m, fwd_tag);
+
+ return (0);
+}
+
+int
+ip_get_fwdtag(struct mbuf *m, struct sockaddr_in *dst, u_short *ifidx)
+{
+ struct m_tag *fwd_tag;
+
+ fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+ if (fwd_tag == NULL) {
+ return (ENOENT);
+ }
+
+ KASSERT(((struct sockaddr *)(fwd_tag+1))->sa_family == AF_INET,
+ ("%s: !AF_INET", __func__));
+
+ if (dst != NULL) {
+ bcopy((fwd_tag+1), dst, sizeof(*dst));
+ }
+
+ if (ifidx != NULL) {
+ /* XXX ifidx is not yet defined */
+ }
+
+ return (0);
+}
+
+void
+ip_flush_fwdtag(struct mbuf *m)
+{
+ struct m_tag *fwd_tag;
+
+ fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+ if (fwd_tag != NULL) {
+ KASSERT(((struct sockaddr *)(fwd_tag+1))->sa_family ==
+ AF_INET, ("%s: !AF_INET", __func__));
+
+ m->m_flags &= ~(M_IP_NEXTHOP | M_FASTFWD_OURS);
+ m_tag_delete(m, fwd_tag);
+ }
+}
Index: sys/netinet/ip_var.h
===================================================================
--- sys/netinet/ip_var.h
+++ sys/netinet/ip_var.h
@@ -236,6 +236,11 @@
extern void (*ip_rsvp_force_done)(struct socket *);
extern int (*rsvp_input_p)(struct mbuf **, int *, int);
+#define IP_HAS_NEXTHOP(m) ((m)->m_flags & M_IP_NEXTHOP)
+int ip_set_fwdtag(struct mbuf *, struct sockaddr_in *, u_short);
+int ip_get_fwdtag(struct mbuf *, struct sockaddr_in *, u_short *);
+void ip_flush_fwdtag(struct mbuf *);
+
VNET_DECLARE(struct pfil_head, inet_pfil_hook); /* packet filter hooks */
#define V_inet_pfil_hook VNET(inet_pfil_hook)
Index: sys/netinet/tcp_input.c
===================================================================
--- sys/netinet/tcp_input.c
+++ sys/netinet/tcp_input.c
@@ -605,6 +605,7 @@
int off0;
int optlen = 0;
#ifdef INET
+ struct sockaddr_in next_hop;
int len;
#endif
int tlen = 0, off;
@@ -615,8 +616,8 @@
uint8_t sig_checked = 0;
#endif
uint8_t iptos;
- struct m_tag *fwd_tag = NULL;
#ifdef INET6
+ struct sockaddr_in6 next_hop6;
struct ip6_hdr *ip6 = NULL;
int isipv6;
#else
@@ -810,22 +811,6 @@
} else
ti_locked = TI_UNLOCKED;
- /*
- * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain.
- */
- if (
-#ifdef INET6
- (isipv6 && (m->m_flags & M_IP6_NEXTHOP))
-#ifdef INET
- || (!isipv6 && (m->m_flags & M_IP_NEXTHOP))
-#endif
-#endif
-#if defined(INET) && !defined(INET6)
- (m->m_flags & M_IP_NEXTHOP)
-#endif
- )
- fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
-
findpcb:
#ifdef INVARIANTS
if (ti_locked == TI_RLOCKED) {
@@ -835,10 +820,11 @@
}
#endif
#ifdef INET6
- if (isipv6 && fwd_tag != NULL) {
- struct sockaddr_in6 *next_hop6;
-
- next_hop6 = (struct sockaddr_in6 *)(fwd_tag + 1);
+ /*
+ * Grab info from IP forward tag prepended to the chain.
+ */
+ if (isipv6 && IP6_HAS_NEXTHOP(m) &&
+ !ip6_get_fwdtag(m, &next_hop6, NULL)) {
/*
* Transparently forwarded. Pretend to be the destination.
* Already got one like this?
@@ -853,11 +839,13 @@
* any hardware-generated hash is ignored.
*/
inp = in6_pcblookup(&V_tcbinfo, &ip6->ip6_src,
- th->th_sport, &next_hop6->sin6_addr,
- next_hop6->sin6_port ? ntohs(next_hop6->sin6_port) :
+ th->th_sport, &next_hop6.sin6_addr,
+ next_hop6.sin6_port ? ntohs(next_hop6.sin6_port) :
th->th_dport, INPLOOKUP_WILDCARD |
INPLOOKUP_WLOCKPCB, m->m_pkthdr.rcvif);
}
+ /* Remove the tag from the packet. We don't need it anymore. */
+ ip6_flush_fwdtag(m);
} else if (isipv6) {
inp = in6_pcblookup_mbuf(&V_tcbinfo, &ip6->ip6_src,
th->th_sport, &ip6->ip6_dst, th->th_dport,
@@ -869,10 +857,10 @@
else
#endif
#ifdef INET
- if (fwd_tag != NULL) {
- struct sockaddr_in *next_hop;
-
- next_hop = (struct sockaddr_in *)(fwd_tag+1);
+ /*
+ * Grab info from IP forward tag prepended to the chain.
+ */
+ if (IP_HAS_NEXTHOP(m) && !ip_get_fwdtag(m, &next_hop, NULL)) {
/*
* Transparently forwarded. Pretend to be the destination.
* already got one like this?
@@ -887,11 +875,13 @@
* any hardware-generated hash is ignored.
*/
inp = in_pcblookup(&V_tcbinfo, ip->ip_src,
- th->th_sport, next_hop->sin_addr,
- next_hop->sin_port ? ntohs(next_hop->sin_port) :
+ th->th_sport, next_hop.sin_addr,
+ next_hop.sin_port ? ntohs(next_hop.sin_port) :
th->th_dport, INPLOOKUP_WILDCARD |
INPLOOKUP_WLOCKPCB, m->m_pkthdr.rcvif);
}
+ /* Remove the tag from the packet. We don't need it anymore. */
+ ip_flush_fwdtag(m);
} else
inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src,
th->th_sport, ip->ip_dst, th->th_dport,
Index: sys/netinet/udp_usrreq.c
===================================================================
--- sys/netinet/udp_usrreq.c
+++ sys/netinet/udp_usrreq.c
@@ -407,7 +407,7 @@
struct ip save_ip;
struct sockaddr_in udp_in;
struct mbuf *m;
- struct m_tag *fwd_tag;
+ struct sockaddr_in next_hop;
int cscov_partial, iphlen;
m = *mp;
@@ -647,14 +647,9 @@
*/
/*
- * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain.
+ * Grab info from IP forward tag prepended to the chain.
*/
- if ((m->m_flags & M_IP_NEXTHOP) &&
- (fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) {
- struct sockaddr_in *next_hop;
-
- next_hop = (struct sockaddr_in *)(fwd_tag + 1);
-
+ if (IP_HAS_NEXTHOP(m) && !ip_get_fwdtag(m, &next_hop, NULL)) {
/*
* Transparently forwarded. Pretend to be the destination.
* Already got one like this?
@@ -668,14 +663,13 @@
* any hardware-generated hash is ignored.
*/
inp = in_pcblookup(pcbinfo, ip->ip_src,
- uh->uh_sport, next_hop->sin_addr,
- next_hop->sin_port ? htons(next_hop->sin_port) :
+ uh->uh_sport, next_hop.sin_addr,
+ next_hop.sin_port ? htons(next_hop.sin_port) :
uh->uh_dport, INPLOOKUP_WILDCARD |
INPLOOKUP_RLOCKPCB, ifp);
}
/* Remove the tag from the packet. We don't need it anymore. */
- m_tag_delete(m, fwd_tag);
- m->m_flags &= ~M_IP_NEXTHOP;
+ ip_flush_fwdtag(m);
} else
inp = in_pcblookup_mbuf(pcbinfo, ip->ip_src, uh->uh_sport,
ip->ip_dst, uh->uh_dport, INPLOOKUP_WILDCARD |
Index: sys/netinet6/ip6_fastfwd.c
===================================================================
--- sys/netinet6/ip6_fastfwd.c
+++ sys/netinet6/ip6_fastfwd.c
@@ -87,7 +87,6 @@
{
struct sockaddr_in6 dst;
struct nhop6_basic nh;
- struct m_tag *fwd_tag;
struct ip6_hdr *ip6;
struct ifnet *rcvif;
uint32_t plen;
@@ -167,24 +166,20 @@
* XXX: should we decrement ip6_hlim in such case?
*
* Also it can forward packet to another destination, e.g.
- * M_IP6_NEXTHOP flag is set and fwd_tag is attached to mbuf.
+ * M_IP6_NEXTHOP flag set and forward tag attached to mbuf.
*/
if (m->m_flags & M_FASTFWD_OURS)
return (m);
ip6 = mtod(m, struct ip6_hdr *);
- if ((m->m_flags & M_IP6_NEXTHOP) &&
- (fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) {
- /*
- * Now we will find route to forwarded by pfil destination.
- */
- bcopy((fwd_tag + 1), &dst, sizeof(dst));
- m->m_flags &= ~M_IP6_NEXTHOP;
- m_tag_delete(m, fwd_tag);
+ if (IP6_HAS_NEXTHOP(m) && !ip6_get_fwdtag(m, &dst, NULL)) {
+ /* Request from pfil to forward to destination */
+ ip6_flush_fwdtag(m);
} else {
/* Update dst since pfil could change it */
dst.sin6_addr = ip6->ip6_dst;
}
+
passin:
/*
* Find route to destination.
@@ -219,7 +214,7 @@
* So, we can just go back to ip6_input.
*
* Also it can forward packet to another destination, e.g.
- * M_IP6_NEXTHOP flag is set and fwd_tag is attached to mbuf.
+ * M_IP6_NEXTHOP flag set and forward tag attached to mbuf.
*/
if (m->m_flags & M_FASTFWD_OURS) {
/*
@@ -232,19 +227,19 @@
* Again. A packet filter could change the destination address.
*/
ip6 = mtod(m, struct ip6_hdr *);
- if (m->m_flags & M_IP6_NEXTHOP)
- fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
- else
- fwd_tag = NULL;
+ if (IP6_HAS_NEXTHOP(m) && !ip6_get_fwdtag(m, &dst, NULL)) {
+ ip6_flush_fwdtag(m);
+
+ /*
+ * Redo route lookup with new destination address
+ */
+ if (ip6_findroute(&nh, &dst, m) != 0) {
+ m = NULL;
+ goto dropout;
+ }
+ } else if (!IN6_ARE_ADDR_EQUAL(&dst.sin6_addr, &ip6->ip6_dst)) {
+ dst.sin6_addr = ip6->ip6_dst;
- if (fwd_tag != NULL ||
- !IN6_ARE_ADDR_EQUAL(&dst.sin6_addr, &ip6->ip6_dst)) {
- if (fwd_tag != NULL) {
- bcopy((fwd_tag + 1), &dst, sizeof(dst));
- m->m_flags &= ~M_IP6_NEXTHOP;
- m_tag_delete(m, fwd_tag);
- } else
- dst.sin6_addr = ip6->ip6_dst;
/*
* Redo route lookup with new destination address
*/
@@ -253,6 +248,7 @@
goto dropout;
}
}
+
passout:
#ifdef IPSTEALTH
if (!V_ip6stealth)
Index: sys/netinet6/ip6_forward.c
===================================================================
--- sys/netinet6/ip6_forward.c
+++ sys/netinet6/ip6_forward.c
@@ -103,7 +103,6 @@
#ifdef IPSEC
struct secpolicy *sp = NULL;
#endif
- struct m_tag *fwd_tag;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
/*
@@ -525,13 +524,17 @@
goto out;
}
/* Or forward to some other address? */
- if ((m->m_flags & M_IP6_NEXTHOP) &&
- (fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) {
+ if (IP6_HAS_NEXTHOP(m)) {
dst = (struct sockaddr_in6 *)&rin6.ro_dst;
- bcopy((fwd_tag+1), dst, sizeof(struct sockaddr_in6));
+ if (ip6_get_fwdtag(m, dst, NULL) != 0) {
+ if (mcopy) {
+ m_freem(m);
+ goto freecopy;
+ }
+ goto bad;
+ }
m->m_flags |= M_SKIP_FIREWALL;
- m->m_flags &= ~M_IP6_NEXTHOP;
- m_tag_delete(m, fwd_tag);
+ ip6_flush_fwdtag(m);
RTFREE(rt);
goto again2;
}
Index: sys/netinet6/ip6_input.c
===================================================================
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -782,8 +782,7 @@
ours = 1;
goto hbhcheck;
}
- if ((m->m_flags & M_IP6_NEXTHOP) &&
- m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL) {
+ if (IP6_HAS_NEXTHOP(m)) {
/*
* Directly ship the packet on. This allows forwarding
* packets originally destined to us to some other directly
Index: sys/netinet6/ip6_output.c
===================================================================
--- sys/netinet6/ip6_output.c
+++ sys/netinet6/ip6_output.c
@@ -322,8 +322,8 @@
int hdrsplit = 0;
int sw_csum, tso;
int needfiblookup;
+ int has_fwd_tag = 0;
uint32_t fibnum;
- struct m_tag *fwd_tag = NULL;
uint32_t id;
if (inp != NULL) {
@@ -547,7 +547,7 @@
ro->ro_dst.sin6_family = AF_INET6;
RT_VALIDATE((struct route *)ro, &inp->inp_rt_cookie, fibnum);
}
- if (ro->ro_rt && fwd_tag == NULL && (ro->ro_rt->rt_flags & RTF_UP) &&
+ if (ro->ro_rt && !has_fwd_tag && (ro->ro_rt->rt_flags & RTF_UP) &&
ro->ro_dst.sin6_family == AF_INET6 &&
IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, &ip6->ip6_dst)) {
rt = ro->ro_rt;
@@ -556,7 +556,7 @@
if (ro->ro_lle)
LLE_FREE(ro->ro_lle); /* zeros ro_lle */
ro->ro_lle = NULL;
- if (fwd_tag == NULL) {
+ if (!has_fwd_tag) {
bzero(&dst_sa, sizeof(dst_sa));
dst_sa.sin6_family = AF_INET6;
dst_sa.sin6_len = sizeof(dst_sa);
@@ -860,13 +860,11 @@
goto done;
}
/* Or forward to some other address? */
- if ((m->m_flags & M_IP6_NEXTHOP) &&
- (fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) {
+ if (IP6_HAS_NEXTHOP(m) && !ip6_get_fwdtag(m, &dst_sa, NULL)) {
dst = (struct sockaddr_in6 *)&ro->ro_dst;
- bcopy((fwd_tag+1), &dst_sa, sizeof(struct sockaddr_in6));
m->m_flags |= M_SKIP_FIREWALL;
- m->m_flags &= ~M_IP6_NEXTHOP;
- m_tag_delete(m, fwd_tag);
+ ip6_flush_fwdtag(m);
+ has_fwd_tag = 1;
goto again;
}
@@ -3096,3 +3094,95 @@
return len;
#undef elen
}
+
+int
+ip6_set_fwdtag(struct mbuf *m, struct sockaddr_in6 *dst, u_short ifidx)
+{
+ struct sockaddr_in6 *sa6;
+ struct m_tag *fwd_tag;
+ int error;
+
+ (void)ifidx; /* XXX: store after dst, or make struct? */
+
+ KASSERT(dst != NULL, ("%s: !dst", __func__));
+ KASSERT(dst->sa_family == AF_INET6, ("%s: !AF_INET6", __func__));
+
+ fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+ if (fwd_tag != NULL) {
+ KASSERT(((struct sockaddr *)(fwd_tag+1))->sa_family ==
+ AF_INET6, ("%s: !AF_INET6", __func__));
+
+ m_tag_unlink(m, fwd_tag);
+ } else {
+ fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD, sizeof(*dst),
+ M_NOWAIT);
+ if (fwd_tag == NULL) {
+ return (ENOBUFS);
+ }
+ }
+
+ sa6 = (struct sockaddr_in6 *)(fwd_tag+1);
+
+ bcopy(dst, sa6, sizeof(*dst));
+
+ /*
+ * If nh6 address is link-local we should convert
+ * it to kernel internal form before doing any
+ * comparisons.
+ */
+ error = sa6_embedscope(sa6, V_ip6_use_defzone);
+ if (error != 0) {
+ m_tag_free(fwd_tag);
+ return (error);
+ }
+
+ if (in6_localip(&sa6->sin6_addr))
+ m->m_flags |= M_FASTFWD_OURS;
+ else
+ m->m_flags &= ~M_FASTFWD_OURS;
+
+ m->m_flags |= M_IP6_NEXTHOP;
+
+ m_tag_prepend(m, fwd_tag);
+
+ return (0);
+}
+
+int
+ip6_get_fwdtag(struct mbuf *m, struct sockaddr_in6 *dst, u_short *ifidx)
+{
+ struct m_tag *fwd_tag;
+
+ fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+ if (fwd_tag == NULL) {
+ return (ENOENT);
+ }
+
+ KASSERT(((struct sockaddr *)(fwd_tag+1))->sa_family == AF_INET6,
+ ("%s: !AF_INET6", __func__));
+
+ if (dst != NULL) {
+ bcopy((fwd_tag+1), dst, sizeof(*dst));
+ }
+
+ if (ifidx != NULL) {
+ /* XXX ifidx is not yet defined */
+ }
+
+ return (0);
+}
+
+void
+ip6_flush_fwdtag(struct mbuf *m)
+{
+ struct m_tag *fwd_tag;
+
+ fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+ if (fwd_tag != NULL) {
+ KASSERT(((struct sockaddr *)(fwd_tag+1))->sa_family ==
+ AF_INET6, ("%s: !AF_INET6", __func__));
+
+ m->m_flags &= ~(M_IP6_NEXTHOP | M_FASTFWD_OURS);
+ m_tag_delete(m, fwd_tag);
+ }
+}
Index: sys/netinet6/ip6_var.h
===================================================================
--- sys/netinet6/ip6_var.h
+++ sys/netinet6/ip6_var.h
@@ -397,6 +397,11 @@
int ip6_fragment(struct ifnet *, struct mbuf *, int, u_char, int,
uint32_t);
+#define IP6_HAS_NEXTHOP(m) ((m)->m_flags & M_IP6_NEXTHOP)
+int ip6_set_fwdtag(struct mbuf *, struct sockaddr_in6 *, u_short);
+int ip6_get_fwdtag(struct mbuf *, struct sockaddr_in6 *, u_short *);
+void ip6_flush_fwdtag(struct mbuf *);
+
int route6_input(struct mbuf **, int *, int);
void frag6_init(void);
Index: sys/netinet6/udp6_usrreq.c
===================================================================
--- sys/netinet6/udp6_usrreq.c
+++ sys/netinet6/udp6_usrreq.c
@@ -204,7 +204,7 @@
int cscov_partial;
int plen, ulen;
struct sockaddr_in6 fromsa;
- struct m_tag *fwd_tag;
+ struct sockaddr_in6 next_hop6;
uint16_t uh_sum;
uint8_t nxt;
@@ -413,14 +413,9 @@
*/
/*
- * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain.
+ * Grab info from IP forward tag prepended to the chain.
*/
- if ((m->m_flags & M_IP6_NEXTHOP) &&
- (fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) {
- struct sockaddr_in6 *next_hop6;
-
- next_hop6 = (struct sockaddr_in6 *)(fwd_tag + 1);
-
+ if (IP6_HAS_NEXTHOP(m) && !ip6_get_fwdtag(m, &next_hop6, NULL)) {
/*
* Transparently forwarded. Pretend to be the destination.
* Already got one like this?
@@ -435,14 +430,13 @@
* any hardware-generated hash is ignored.
*/
inp = in6_pcblookup(pcbinfo, &ip6->ip6_src,
- uh->uh_sport, &next_hop6->sin6_addr,
- next_hop6->sin6_port ? htons(next_hop6->sin6_port) :
+ uh->uh_sport, &next_hop6.sin6_addr,
+ next_hop6.sin6_port ? htons(next_hop6.sin6_port) :
uh->uh_dport, INPLOOKUP_WILDCARD |
INPLOOKUP_RLOCKPCB, m->m_pkthdr.rcvif);
}
/* Remove the tag from the packet. We don't need it anymore. */
- m_tag_delete(m, fwd_tag);
- m->m_flags &= ~M_IP6_NEXTHOP;
+ ip6_flush_fwdtag(m);
} else
inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_src,
uh->uh_sport, &ip6->ip6_dst, uh->uh_dport,
Index: sys/netpfil/ipfw/ip_fw_pfil.c
===================================================================
--- sys/netpfil/ipfw/ip_fw_pfil.c
+++ sys/netpfil/ipfw/ip_fw_pfil.c
@@ -165,66 +165,25 @@
ret = EACCES;
#else
{
- struct m_tag *fwd_tag;
- size_t len;
-
KASSERT(args.next_hop == NULL || args.next_hop6 == NULL,
("%s: both next_hop=%p and next_hop6=%p not NULL", __func__,
args.next_hop, args.next_hop6));
#ifdef INET6
- if (args.next_hop6 != NULL)
- len = sizeof(struct sockaddr_in6);
-#endif
-#ifdef INET
- if (args.next_hop != NULL)
- len = sizeof(struct sockaddr_in);
-#endif
-
- /* Incoming packets should not be tagged so we do not
- * m_tag_find. Outgoing packets may be tagged, so we
- * reuse the tag if present.
- */
- fwd_tag = (dir == DIR_IN) ? NULL :
- m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL);
- if (fwd_tag != NULL) {
- m_tag_unlink(*m0, fwd_tag);
- } else {
- fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD, len,
- M_NOWAIT);
- if (fwd_tag == NULL) {
- ret = EACCES;
- break; /* i.e. drop */
- }
- }
-#ifdef INET6
if (args.next_hop6 != NULL) {
- struct sockaddr_in6 *sa6;
-
- sa6 = (struct sockaddr_in6 *)(fwd_tag + 1);
- bcopy(args.next_hop6, sa6, len);
- /*
- * If nh6 address is link-local we should convert
- * it to kernel internal form before doing any
- * comparisons.
- */
- if (sa6_embedscope(sa6, V_ip6_use_defzone) != 0) {
+ if (ip6_set_fwdtag(*m0, args.next_hop6, 0)) {
ret = EACCES;
break;
}
- if (in6_localip(&sa6->sin6_addr))
- (*m0)->m_flags |= M_FASTFWD_OURS;
- (*m0)->m_flags |= M_IP6_NEXTHOP;
}
#endif
#ifdef INET
if (args.next_hop != NULL) {
- bcopy(args.next_hop, (fwd_tag+1), len);
- if (in_localip(args.next_hop->sin_addr))
- (*m0)->m_flags |= M_FASTFWD_OURS;
- (*m0)->m_flags |= M_IP_NEXTHOP;
+ if (ip_set_fwdtag(*m0, args.next_hop, 0)) {
+ ret = EACCES;
+ break;
+ }
}
#endif
- m_tag_prepend(*m0, fwd_tag);
}
#endif /* INET || INET6 */
break;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 18, 11:20 PM (5 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23898874
Default Alt Text
D8877.id23178.diff (21 KB)
Attached To
Mode
D8877: pf|ipfw|netinet6?: shared IP forwarding
Attached
Detach File
Event Timeline
Log In to Comment