Page MenuHomeFreeBSD

D2015.diff
No OneTemporary

D2015.diff

Index: sbin/ipfw/ipfw.8
===================================================================
--- sbin/ipfw/ipfw.8
+++ sbin/ipfw/ipfw.8
@@ -2078,6 +2078,8 @@
maximum number of connections.
.It Cm ipv4
IPv4 nexthop to fwd packets to.
+.It Cm ipv6
+IPv6 nexthop to fwd packets to.
.El
.Pp
The
Index: sbin/ipfw/tables.c
===================================================================
--- sbin/ipfw/tables.c
+++ sbin/ipfw/tables.c
@@ -35,6 +35,7 @@
#include <netinet/in.h>
#include <netinet/ip_fw.h>
#include <arpa/inet.h>
+#include <netdb.h>
#include "ipfw2.h"
@@ -1384,6 +1385,7 @@
tentry_fill_value(ipfw_obj_header *oh, ipfw_obj_tentry *tent, char *arg,
uint8_t type, uint32_t vmask)
{
+ struct addrinfo hints, *res;
uint32_t a4, flag, val, vm;
ipfw_table_value *v;
uint32_t i;
@@ -1494,9 +1496,19 @@
}
break;
case IPFW_VTYPE_NH6:
- if (strchr(n, ':') != NULL &&
- inet_pton(AF_INET6, n, &v->nh6) == 1)
- break;
+ if (strchr(n, ':') != NULL) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(n, NULL, &hints, &res) == 0) {
+ v->nh6 = ((struct sockaddr_in6 *)
+ res->ai_addr)->sin6_addr;
+ v->zoneid = ((struct sockaddr_in6 *)
+ res->ai_addr)->sin6_scope_id;
+ freeaddrinfo(res);
+ break;
+ }
+ }
etype = "ipv6";
break;
}
@@ -1643,10 +1655,11 @@
table_show_value(char *buf, size_t bufsize, ipfw_table_value *v,
uint32_t vmask, int print_ip)
{
+ char abuf[INET6_ADDRSTRLEN + IF_NAMESIZE + 2];
+ struct sockaddr_in6 sa6;
uint32_t flag, i, l;
size_t sz;
struct in_addr a4;
- char abuf[INET6_ADDRSTRLEN];
sz = bufsize;
@@ -1702,8 +1715,15 @@
l = snprintf(buf, sz, "%d,", v->dscp);
break;
case IPFW_VTYPE_NH6:
- inet_ntop(AF_INET6, &v->nh6, abuf, sizeof(abuf));
- l = snprintf(buf, sz, "%s,", abuf);
+ sa6.sin6_family = AF_INET6;
+ sa6.sin6_len = sizeof(sa6);
+ sa6.sin6_addr = v->nh6;
+ sa6.sin6_port = 0;
+ sa6.sin6_scope_id = v->zoneid;
+ if (getnameinfo((const struct sockaddr *)&sa6,
+ sa6.sin6_len, abuf, sizeof(abuf), NULL, 0,
+ NI_NUMERICHOST) == 0)
+ l = snprintf(buf, sz, "%s,", abuf);
break;
}
@@ -1862,11 +1882,12 @@
uint32_t nat; /* O_NAT */
uint32_t nh4;
uint8_t dscp;
- uint8_t spare0[3];
+ uint8_t spare0;
+ uint16_t spare1;
/* -- 32 bytes -- */
struct in6_addr nh6;
uint32_t limit; /* O_LIMIT */
- uint32_t spare1;
+ uint32_t zoneid;
uint64_t refcnt; /* Number of references */
};
Index: sys/netinet/ip_fw.h
===================================================================
--- sys/netinet/ip_fw.h
+++ sys/netinet/ip_fw.h
@@ -721,7 +721,7 @@
#define IPFW_VTYPE_TAG 0x00000020 /* tag/untag */
#define IPFW_VTYPE_DIVERT 0x00000040 /* divert/tee */
#define IPFW_VTYPE_NETGRAPH 0x00000080 /* netgraph/ngtee */
-#define IPFW_VTYPE_LIMIT 0x00000100 /* IPv6 nexthop */
+#define IPFW_VTYPE_LIMIT 0x00000100 /* limit */
#define IPFW_VTYPE_NH4 0x00000200 /* IPv4 nexthop */
#define IPFW_VTYPE_NH6 0x00000400 /* IPv6 nexthop */
@@ -817,10 +817,11 @@
uint32_t nat; /* O_NAT */
uint32_t nh4;
uint8_t dscp;
- uint8_t spare0[3];
+ uint8_t spare0;
+ uint16_t spare1;
struct in6_addr nh6;
uint32_t limit; /* O_LIMIT */
- uint32_t spare1;
+ uint32_t zoneid; /* scope zone id for nh6 */
uint64_t reserved;
} ipfw_table_value;
Index: sys/netpfil/ipfw/ip_fw2.c
===================================================================
--- sys/netpfil/ipfw/ip_fw2.c
+++ sys/netpfil/ipfw/ip_fw2.c
@@ -2387,13 +2387,41 @@
if (q == NULL || q->rule != f ||
dyn_dir == MATCH_FORWARD) {
struct sockaddr_in *sa;
+
sa = &(((ipfw_insn_sa *)cmd)->sa);
if (sa->sin_addr.s_addr == INADDR_ANY) {
- bcopy(sa, &args->hopstore,
- sizeof(*sa));
- args->hopstore.sin_addr.s_addr =
- htonl(tablearg);
- args->next_hop = &args->hopstore;
+#ifdef INET6
+ /*
+ * We use O_FORWARD_IP opcode for
+ * fwd rule with tablearg, but tables
+ * now support IPv6 address. And when
+ * packet that we are inspecting is
+ * IPv6 packet, we can use nh6 from
+ * table value as IPv6 address for
+ * forwarding.
+ */
+ if (is_ipv6) {
+ struct sockaddr_in6 *sa6;
+
+ sa6 = args->next_hop6 =
+ &args->hopstore6;
+ sa6->sin6_family = AF_INET6;
+ sa6->sin6_len = sizeof(*sa6);
+ sa6->sin6_addr = TARG_VAL(
+ chain, tablearg, nh6);
+ sa6->sin6_scope_id = TARG_VAL(
+ chain, tablearg, zoneid);
+ } else
+#endif
+ {
+ sa = args->next_hop =
+ &args->hopstore;
+ sa->sin_family = AF_INET;
+ sa->sin_len = sizeof(*sa);
+ sa->sin_addr.s_addr = htonl(
+ TARG_VAL(chain, tablearg,
+ nh4));
+ }
} else {
args->next_hop = sa;
}
Index: sys/netpfil/ipfw/ip_fw_pfil.c
===================================================================
--- sys/netpfil/ipfw/ip_fw_pfil.c
+++ sys/netpfil/ipfw/ip_fw_pfil.c
@@ -59,6 +59,7 @@
#ifdef INET6
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
+#include <netinet6/scope6_var.h>
#endif
#include <netgraph/ng_ipfw.h>
@@ -197,8 +198,20 @@
}
#ifdef INET6
if (args.next_hop6 != NULL) {
- bcopy(args.next_hop6, (fwd_tag+1), len);
- if (in6_localip(&args.next_hop6->sin6_addr))
+ 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) {
+ ret = EACCES;
+ break;
+ }
+ if (in6_localip(&sa6->sin6_addr))
(*m0)->m_flags |= M_FASTFWD_OURS;
(*m0)->m_flags |= M_IP6_NEXTHOP;
}
Index: sys/netpfil/ipfw/ip_fw_private.h
===================================================================
--- sys/netpfil/ipfw/ip_fw_private.h
+++ sys/netpfil/ipfw/ip_fw_private.h
@@ -102,7 +102,10 @@
struct inpcb *inp;
struct _ip6dn_args dummypar; /* dummynet->ip6_output */
- struct sockaddr_in hopstore; /* store here if cannot use a pointer */
+ union { /* store here if cannot use a pointer */
+ struct sockaddr_in hopstore;
+ struct sockaddr_in6 hopstore6;
+ };
};
MALLOC_DECLARE(M_IPFW);
@@ -294,11 +297,12 @@
uint32_t nat; /* O_NAT */
uint32_t nh4;
uint8_t dscp;
- uint8_t spare0[3];
+ uint8_t spare0;
+ uint16_t spare1;
/* -- 32 bytes -- */
struct in6_addr nh6;
uint32_t limit; /* O_LIMIT */
- uint32_t spare1;
+ uint32_t zoneid; /* scope zone id for nh6 */
uint64_t refcnt; /* Number of references */
};
Index: sys/netpfil/ipfw/ip_fw_table_value.c
===================================================================
--- sys/netpfil/ipfw/ip_fw_table_value.c
+++ sys/netpfil/ipfw/ip_fw_table_value.c
@@ -117,6 +117,7 @@
_MCPY(dscp, IPFW_VTYPE_DSCP);
_MCPY(nh4, IPFW_VTYPE_NH4);
_MCPY(nh6, IPFW_VTYPE_NH6);
+ _MCPY(zoneid, IPFW_VTYPE_NH6);
#undef _MCPY
}
@@ -666,6 +667,7 @@
v.nh4 = iv->nh4;
v.nh6 = iv->nh6;
v.limit = iv->limit;
+ v.zoneid = iv->zoneid;
memcpy(iv, &v, sizeof(ipfw_table_value));
}
@@ -691,6 +693,7 @@
iv.limit = v->limit;
iv.nh4 = v->nh4;
iv.nh6 = v->nh6;
+ iv.zoneid = v->zoneid;
memcpy(piv, &iv, sizeof(iv));
}

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 22, 8:56 PM (3 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31999245
Default Alt Text
D2015.diff (7 KB)

Event Timeline