summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netpfil
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-09 14:19:03 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-10 09:53:34 +0100
commit75b706fde4cbf82bcd41a1cec319778aa0f8eb2d (patch)
treeea39a351a1f6337b5a5dd6036314693adef5ffe6 /freebsd/sys/netpfil
parentVMSTAT(8): Port to RTEMS (diff)
downloadrtems-libbsd-75b706fde4cbf82bcd41a1cec319778aa0f8eb2d.tar.bz2
Update to FreeBSD head 2016-12-10
Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
Diffstat (limited to 'freebsd/sys/netpfil')
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw2.c4
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c11
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_pfil.c24
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_table.c50
-rw-r--r--freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c4
-rw-r--r--freebsd/sys/netpfil/pf/if_pflog.c2
-rw-r--r--freebsd/sys/netpfil/pf/if_pfsync.c9
-rw-r--r--freebsd/sys/netpfil/pf/pf.c65
-rw-r--r--freebsd/sys/netpfil/pf/pf_if.c2
-rw-r--r--freebsd/sys/netpfil/pf/pf_ioctl.c4
-rw-r--r--freebsd/sys/netpfil/pf/pf_norm.c2
11 files changed, 91 insertions, 86 deletions
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw2.c b/freebsd/sys/netpfil/ipfw/ip_fw2.c
index a3a11819..945ad170 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw2.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw2.c
@@ -2728,6 +2728,7 @@ ipfw_init(void)
default_fw_tables = IPFW_TABLES_MAX;
ipfw_init_sopt_handler();
+ ipfw_init_obj_rewriter();
ipfw_iface_init();
return (error);
}
@@ -2742,6 +2743,7 @@ ipfw_destroy(void)
ipfw_iface_destroy();
ipfw_destroy_sopt_handler();
+ ipfw_destroy_obj_rewriter();
printf("IP firewall unloaded\n");
}
#endif /* __rtems__ */
@@ -2777,7 +2779,6 @@ vnet_ipfw_init(const void *unused)
/* Init shared services hash table */
ipfw_init_srv(chain);
- ipfw_init_obj_rewriter();
ipfw_init_counters();
/* insert the default rule and create the initial map */
chain->n_rules = 1;
@@ -2883,7 +2884,6 @@ vnet_ipfw_uninit(const void *unused)
IPFW_LOCK_DESTROY(chain);
ipfw_dyn_uninit(1); /* free the remaining parts */
ipfw_destroy_counters();
- ipfw_destroy_obj_rewriter();
ipfw_bpf_uninit(last);
return (0);
}
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c b/freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c
index 4696faac..5694b1d1 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c
@@ -258,9 +258,8 @@ hash_packet6(struct ipfw_flow_id *id)
i = (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
(id->dst_ip6.__u6_addr.__u6_addr32[3]) ^
(id->src_ip6.__u6_addr.__u6_addr32[2]) ^
- (id->src_ip6.__u6_addr.__u6_addr32[3]) ^
- (id->dst_port) ^ (id->src_port);
- return i;
+ (id->src_ip6.__u6_addr.__u6_addr32[3]);
+ return ntohl(i);
}
#endif
@@ -279,9 +278,9 @@ hash_packet(struct ipfw_flow_id *id, int buckets)
i = hash_packet6(id);
else
#endif /* INET6 */
- i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
- i &= (buckets - 1);
- return i;
+ i = (id->dst_ip) ^ (id->src_ip);
+ i ^= (id->dst_port) ^ (id->src_port);
+ return (i & (buckets - 1));
}
#if 0
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_pfil.c b/freebsd/sys/netpfil/ipfw/ip_fw_pfil.c
index 59c13aa5..167d2028 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_pfil.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_pfil.c
@@ -305,11 +305,9 @@ again:
/*
* ipfw processing for ethernet packets (in and out).
- * Inteface is NULL from ether_demux, and ifp from
- * ether_output_frame.
*/
int
-ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
+ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
struct ether_header *eh;
@@ -319,20 +317,15 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
struct ip_fw_args args;
struct m_tag *mtag;
- /* fetch start point from rule, if any */
+ /* fetch start point from rule, if any. remove the tag if present. */
mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
if (mtag == NULL) {
args.rule.slot = 0;
} else {
- /* dummynet packet, already partially processed */
- struct ipfw_rule_ref *r;
-
- /* XXX can we free it after use ? */
- mtag->m_tag_id = PACKET_TAG_NONE;
- r = (struct ipfw_rule_ref *)(mtag + 1);
- if (r->info & IPFW_ONEPASS)
+ args.rule = *((struct ipfw_rule_ref *)(mtag+1));
+ m_tag_delete(*m0, mtag);
+ if (args.rule.info & IPFW_ONEPASS)
return (0);
- args.rule = *r;
}
/* I need some amt of data to be contiguous */
@@ -350,7 +343,7 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
m_adj(m, ETHER_HDR_LEN); /* strip ethernet header */
args.m = m; /* the packet we are looking at */
- args.oif = dir == PFIL_OUT ? dst: NULL; /* destination, if any */
+ args.oif = dir == PFIL_OUT ? ifp: NULL; /* destination, if any */
args.next_hop = NULL; /* we do not support forward yet */
args.next_hop6 = NULL; /* we do not support forward yet */
args.eh = &save_eh; /* MAC header for bridged/MAC packets */
@@ -385,14 +378,13 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
case IP_FW_DUMMYNET:
ret = EACCES;
- int dir;
if (ip_dn_io_ptr == NULL)
break; /* i.e. drop */
*m0 = NULL;
- dir = PROTO_LAYER2 | (dst ? DIR_OUT : DIR_IN);
- ip_dn_io_ptr(&m, dir, &args);
+ dir = (dir == PFIL_IN) ? DIR_IN : DIR_OUT;
+ ip_dn_io_ptr(&m, dir | PROTO_LAYER2, &args);
return 0;
default:
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_table.c b/freebsd/sys/netpfil/ipfw/ip_fw_table.c
index 9d2baad2..17c5f017 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_table.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_table.c
@@ -1089,6 +1089,7 @@ find_table_entry(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
struct table_config *tc;
struct table_algo *ta;
struct table_info *kti;
+ struct table_value *pval;
struct namedobj_instance *ni;
int error;
size_t sz;
@@ -1134,7 +1135,10 @@ find_table_entry(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
return (ENOTSUP);
error = ta->find_tentry(tc->astate, kti, tent);
-
+ if (error == 0) {
+ pval = get_table_value(ch, tc, tent->v.kidx);
+ ipfw_export_table_value_v1(pval, &tent->v.value);
+ }
IPFW_UH_RUNLOCK(ch);
return (error);
@@ -2878,13 +2882,12 @@ table_manage_sets(struct ip_fw_chain *ch, uint16_t set, uint8_t new_set,
switch (cmd) {
case SWAP_ALL:
case TEST_ALL:
+ case MOVE_ALL:
/*
- * Return success for TEST_ALL, since nothing prevents
- * move rules from one set to another. All tables are
- * accessible from all sets when per-set tables sysctl
- * is disabled.
+ * Always return success, the real action and decision
+ * should make table_manage_sets_all().
*/
- case MOVE_ALL:
+ return (0);
case TEST_ONE:
case MOVE_ONE:
/*
@@ -2909,6 +2912,39 @@ table_manage_sets(struct ip_fw_chain *ch, uint16_t set, uint8_t new_set,
set, new_set, cmd));
}
+/*
+ * We register several opcode rewriters for lookup tables.
+ * All tables opcodes have the same ETLV type, but different subtype.
+ * To avoid invoking sets handler several times for XXX_ALL commands,
+ * we use separate manage_sets handler. O_RECV has the lowest value,
+ * so it should be called first.
+ */
+static int
+table_manage_sets_all(struct ip_fw_chain *ch, uint16_t set, uint8_t new_set,
+ enum ipfw_sets_cmd cmd)
+{
+
+ switch (cmd) {
+ case SWAP_ALL:
+ case TEST_ALL:
+ /*
+ * Return success for TEST_ALL, since nothing prevents
+ * move rules from one set to another. All tables are
+ * accessible from all sets when per-set tables sysctl
+ * is disabled.
+ */
+ case MOVE_ALL:
+ if (V_fw_tables_sets == 0)
+ return (0);
+ break;
+ default:
+ return (table_manage_sets(ch, set, new_set, cmd));
+ }
+ /* Use generic sets handler when per-set sysctl is enabled. */
+ return (ipfw_obj_manage_sets(CHAIN_TO_NI(ch), IPFW_TLV_TBL_NAME,
+ set, new_set, cmd));
+}
+
static struct opcode_obj_rewrite opcodes[] = {
{
.opcode = O_IP_SRC_LOOKUP,
@@ -2958,7 +2994,7 @@ static struct opcode_obj_rewrite opcodes[] = {
.find_byname = table_findbyname,
.find_bykidx = table_findbykidx,
.create_object = create_table_compat,
- .manage_sets = table_manage_sets,
+ .manage_sets = table_manage_sets_all,
},
{
.opcode = O_VIA,
diff --git a/freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c b/freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c
index d2507674..2f881476 100644
--- a/freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c
+++ b/freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c
@@ -1258,9 +1258,9 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t aaddr, uint16_t aport,
*/
mtu -= sizeof(struct ip6_hdr) - sizeof(struct ip);
break;
- case ICMP6_TIME_EXCEED_TRANSIT:
+ case ICMP6_TIME_EXCEEDED:
type = ICMP_TIMXCEED;
- code = ICMP_TIMXCEED_INTRANS;
+ code = icmp6->icmp6_code;
break;
case ICMP6_PARAM_PROB:
switch (icmp6->icmp6_code) {
diff --git a/freebsd/sys/netpfil/pf/if_pflog.c b/freebsd/sys/netpfil/pf/if_pflog.c
index 3a364abc..09473f17 100644
--- a/freebsd/sys/netpfil/pf/if_pflog.c
+++ b/freebsd/sys/netpfil/pf/if_pflog.c
@@ -223,7 +223,7 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
if (am == NULL) {
hdr.rulenr = htonl(rm->nr);
- hdr.subrulenr = 1;
+ hdr.subrulenr = -1;
} else {
hdr.rulenr = htonl(am->nr);
hdr.subrulenr = htonl(rm->nr);
diff --git a/freebsd/sys/netpfil/pf/if_pfsync.c b/freebsd/sys/netpfil/pf/if_pfsync.c
index d6a0dfc0..d82a6b74 100644
--- a/freebsd/sys/netpfil/pf/if_pfsync.c
+++ b/freebsd/sys/netpfil/pf/if_pfsync.c
@@ -1511,7 +1511,7 @@ pfsync_sendout(int schedswi)
struct ip *ip;
struct pfsync_header *ph;
struct pfsync_subheader *subh;
- struct pf_state *st;
+ struct pf_state *st, *st_next;
struct pfsync_upd_req_item *ur;
int offset;
int q, count = 0;
@@ -1561,7 +1561,7 @@ pfsync_sendout(int schedswi)
offset += sizeof(*subh);
count = 0;
- TAILQ_FOREACH(st, &sc->sc_qs[q], sync_list) {
+ TAILQ_FOREACH_SAFE(st, &sc->sc_qs[q], sync_list, st_next) {
KASSERT(st->sync_state == q,
("%s: st->sync_state == q",
__func__));
@@ -1933,6 +1933,8 @@ pfsync_delete_state(struct pf_state *st)
if (sc->sc_len == PFSYNC_MINPKT)
callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout, V_pfsyncif);
+ pf_ref_state(st);
+
switch (st->sync_state) {
case PFSYNC_S_INS:
/* We never got to tell the world so just forget about it. */
@@ -1952,6 +1954,9 @@ pfsync_delete_state(struct pf_state *st)
default:
panic("%s: unexpected sync state %d", __func__, st->sync_state);
}
+
+ pf_release_state(st);
+
PFSYNC_UNLOCK(sc);
}
diff --git a/freebsd/sys/netpfil/pf/pf.c b/freebsd/sys/netpfil/pf/pf.c
index 7ac181b5..5b6be3cb 100644
--- a/freebsd/sys/netpfil/pf/pf.c
+++ b/freebsd/sys/netpfil/pf/pf.c
@@ -3644,7 +3644,7 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
s->timeout = PFTM_OTHER_FIRST_PACKET;
}
- if (r->rt && r->rt != PF_FASTROUTE) {
+ if (r->rt) {
if (pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL, &sn)) {
REASON_SET(&reason, PFRES_MAPFAILED);
pf_src_tree_remove_state(s);
@@ -5451,41 +5451,24 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
dst.sin_len = sizeof(dst);
dst.sin_addr = ip->ip_dst;
- if (r->rt == PF_FASTROUTE) {
- struct nhop4_basic nh4;
-
- if (s)
- PF_STATE_UNLOCK(s);
-
- if (fib4_lookup_nh_basic(M_GETFIB(m0), ip->ip_dst, 0,
- m0->m_pkthdr.flowid, &nh4) != 0) {
- KMOD_IPSTAT_INC(ips_noroute);
- error = EHOSTUNREACH;
- goto bad;
- }
-
- ifp = nh4.nh_ifp;
- dst.sin_addr = nh4.nh_addr;
+ if (TAILQ_EMPTY(&r->rpool.list)) {
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
+ goto bad_locked;
+ }
+ if (s == NULL) {
+ pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
+ &naddr, NULL, &sn);
+ if (!PF_AZERO(&naddr, AF_INET))
+ dst.sin_addr.s_addr = naddr.v4.s_addr;
+ ifp = r->rpool.cur->kif ?
+ r->rpool.cur->kif->pfik_ifp : NULL;
} else {
- if (TAILQ_EMPTY(&r->rpool.list)) {
- DPFPRINTF(PF_DEBUG_URGENT,
- ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
- goto bad_locked;
- }
- if (s == NULL) {
- pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
- &naddr, NULL, &sn);
- if (!PF_AZERO(&naddr, AF_INET))
- dst.sin_addr.s_addr = naddr.v4.s_addr;
- ifp = r->rpool.cur->kif ?
- r->rpool.cur->kif->pfik_ifp : NULL;
- } else {
- if (!PF_AZERO(&s->rt_addr, AF_INET))
- dst.sin_addr.s_addr =
- s->rt_addr.v4.s_addr;
- ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
- PF_STATE_UNLOCK(s);
- }
+ if (!PF_AZERO(&s->rt_addr, AF_INET))
+ dst.sin_addr.s_addr =
+ s->rt_addr.v4.s_addr;
+ ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
+ PF_STATE_UNLOCK(s);
}
if (ifp == NULL)
goto bad;
@@ -5627,16 +5610,6 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
dst.sin6_len = sizeof(dst);
dst.sin6_addr = ip6->ip6_dst;
- /* Cheat. XXX why only in the v6 case??? */
- if (r->rt == PF_FASTROUTE) {
- if (s)
- PF_STATE_UNLOCK(s);
- m0->m_flags |= M_SKIP_FIREWALL;
- ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
- *m = NULL;
- return;
- }
-
if (TAILQ_EMPTY(&r->rpool.list)) {
DPFPRINTF(PF_DEBUG_URGENT,
("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
@@ -5932,7 +5905,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
pd.sidx = (dir == PF_IN) ? 0 : 1;
pd.didx = (dir == PF_IN) ? 1 : 0;
pd.af = AF_INET;
- pd.tos = h->ip_tos;
+ pd.tos = h->ip_tos & ~IPTOS_ECN_MASK;
pd.tot_len = ntohs(h->ip_len);
/* handle fragments that didn't get reassembled by normalization */
diff --git a/freebsd/sys/netpfil/pf/pf_if.c b/freebsd/sys/netpfil/pf/pf_if.c
index d1c54b22..29f8e941 100644
--- a/freebsd/sys/netpfil/pf/pf_if.c
+++ b/freebsd/sys/netpfil/pf/pf_if.c
@@ -525,7 +525,7 @@ pfi_instance_add(struct ifnet *ifp, int net, int flags)
int net2, af;
IF_ADDR_RLOCK(ifp);
- TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_list) {
+ TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
if (ia->ifa_addr == NULL)
continue;
af = ia->ifa_addr->sa_family;
diff --git a/freebsd/sys/netpfil/pf/pf_ioctl.c b/freebsd/sys/netpfil/pf/pf_ioctl.c
index 9c1523ca..076ed5f8 100644
--- a/freebsd/sys/netpfil/pf/pf_ioctl.c
+++ b/freebsd/sys/netpfil/pf/pf_ioctl.c
@@ -1274,7 +1274,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
pf_mv_pool(&V_pf_pabuf, &rule->rpool.list);
if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
(rule->action == PF_BINAT)) && rule->anchor == NULL) ||
- (rule->rt > PF_FASTROUTE)) &&
+ (rule->rt > PF_NOPFROUTE)) &&
(TAILQ_FIRST(&rule->rpool.list) == NULL))
error = EINVAL;
@@ -1539,7 +1539,7 @@ DIOCADDRULE_error:
if (((((newrule->action == PF_NAT) ||
(newrule->action == PF_RDR) ||
(newrule->action == PF_BINAT) ||
- (newrule->rt > PF_FASTROUTE)) &&
+ (newrule->rt > PF_NOPFROUTE)) &&
!newrule->anchor)) &&
(TAILQ_FIRST(&newrule->rpool.list) == NULL))
error = EINVAL;
diff --git a/freebsd/sys/netpfil/pf/pf_norm.c b/freebsd/sys/netpfil/pf/pf_norm.c
index 86d2c8eb..42b44c70 100644
--- a/freebsd/sys/netpfil/pf/pf_norm.c
+++ b/freebsd/sys/netpfil/pf/pf_norm.c
@@ -1813,7 +1813,7 @@ pf_scrub_ip(struct mbuf **m0, u_int32_t flags, u_int8_t min_ttl, u_int8_t tos)
u_int16_t ov, nv;
ov = *(u_int16_t *)h;
- h->ip_tos = tos;
+ h->ip_tos = tos | (h->ip_tos & IPTOS_ECN_MASK);
nv = *(u_int16_t *)h;
h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);