Page MenuHomeFreeBSD

D8877.id23178.diff
No OneTemporary

D8877.id23178.diff

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

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)

Event Timeline