diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-12-09 14:19:03 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-10 09:53:34 +0100 |
commit | 75b706fde4cbf82bcd41a1cec319778aa0f8eb2d (patch) | |
tree | ea39a351a1f6337b5a5dd6036314693adef5ffe6 /freebsd/sys/netpfil | |
parent | VMSTAT(8): Port to RTEMS (diff) | |
download | rtems-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.c | 4 | ||||
-rw-r--r-- | freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c | 11 | ||||
-rw-r--r-- | freebsd/sys/netpfil/ipfw/ip_fw_pfil.c | 24 | ||||
-rw-r--r-- | freebsd/sys/netpfil/ipfw/ip_fw_table.c | 50 | ||||
-rw-r--r-- | freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c | 4 | ||||
-rw-r--r-- | freebsd/sys/netpfil/pf/if_pflog.c | 2 | ||||
-rw-r--r-- | freebsd/sys/netpfil/pf/if_pfsync.c | 9 | ||||
-rw-r--r-- | freebsd/sys/netpfil/pf/pf.c | 65 | ||||
-rw-r--r-- | freebsd/sys/netpfil/pf/pf_if.c | 2 | ||||
-rw-r--r-- | freebsd/sys/netpfil/pf/pf_ioctl.c | 4 | ||||
-rw-r--r-- | freebsd/sys/netpfil/pf/pf_norm.c | 2 |
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); |