mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-22 09:43:47 +00:00
Cleanup the interface to ip_fw_chk, two of the input arguments
were totally useless and have been removed. ip_input.c, ip_output.c: Properly initialize the "ip" pointer in case the firewall does an m_pullup() on the packet. Remove some debugging code forgotten long ago. ip_fw.[ch], bridge.c: Prepare the grounds for matching MAC header fields in bridged packets, so we can have 'etherfw' functionality without a lot of kernel and userland bloat.
This commit is contained in:
parent
d8f4f6a404
commit
d60315bef5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=96245
|
@ -859,15 +859,10 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
|
|||
#endif
|
||||
(IPFW_LOADED && bdg_ipfw != 0))) {
|
||||
|
||||
struct ip *ip ;
|
||||
int i;
|
||||
|
||||
if (rule != NULL) /* dummynet packet, already partially processed */
|
||||
goto forward; /* HACK! I should obey the fw_one_pass */
|
||||
if (ntohs(save_eh.ether_type) != ETHERTYPE_IP)
|
||||
goto forward ; /* not an IP packet, ipfw is not appropriate */
|
||||
if (m0->m_pkthdr.len < sizeof(struct ip) )
|
||||
goto forward ; /* header too short for an IP pkt, cannot filter */
|
||||
/*
|
||||
* i need some amt of data to be contiguous, and in case others need
|
||||
* the packet (shared==1) also better be in the first mbuf.
|
||||
|
@ -881,48 +876,51 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* before calling the firewall, swap fields the same as IP does.
|
||||
* here we assume the pkt is an IP one and the header is contiguous
|
||||
*/
|
||||
ip = mtod(m0, struct ip *);
|
||||
ip->ip_len = ntohs(ip->ip_len);
|
||||
ip->ip_off = ntohs(ip->ip_off);
|
||||
|
||||
#ifdef PFIL_HOOKS
|
||||
/*
|
||||
* NetBSD-style generic packet filter, pfil(9), hooks.
|
||||
* Enables ipf(8) in bridging.
|
||||
*/
|
||||
#ifdef PFIL_HOOKS
|
||||
for (; pfh; pfh = TAILQ_NEXT(pfh, pfil_link))
|
||||
if (pfh->pfil_func) {
|
||||
rv = pfh->pfil_func(ip, ip->ip_hl << 2, src, 0, &m0);
|
||||
if (rv != 0 || m0 == NULL)
|
||||
return m0;
|
||||
ip = mtod(m0, struct ip *);
|
||||
}
|
||||
if (m0->m_pkthdr.len >= sizeof(struct ip) &&
|
||||
ntohs(save_eh.ether_type) == ETHERTYPE_IP) {
|
||||
/*
|
||||
* before calling the firewall, swap fields the same as IP does.
|
||||
* here we assume the pkt is an IP one and the header is contiguous
|
||||
*/
|
||||
struct ip *ip = mtod(m0, struct ip *);
|
||||
|
||||
ip->ip_len = ntohs(ip->ip_len);
|
||||
ip->ip_off = ntohs(ip->ip_off);
|
||||
|
||||
for (; pfh; pfh = TAILQ_NEXT(pfh, pfil_link))
|
||||
if (pfh->pfil_func) {
|
||||
rv = pfh->pfil_func(ip, ip->ip_hl << 2, src, 0, &m0);
|
||||
if (rv != 0 || m0 == NULL)
|
||||
return m0;
|
||||
ip = mtod(m0, struct ip *);
|
||||
}
|
||||
/*
|
||||
* If we get here, the firewall has passed the pkt, but the mbuf
|
||||
* pointer might have changed. Restore ip and the fields ntohs()'d.
|
||||
*/
|
||||
ip = mtod(m0, struct ip *);
|
||||
ip->ip_len = htons(ip->ip_len);
|
||||
ip->ip_off = htons(ip->ip_off);
|
||||
}
|
||||
#endif /* PFIL_HOOKS */
|
||||
|
||||
/*
|
||||
* The third parameter to the firewall code is the dst. interface.
|
||||
* The second parameter to the firewall code is the dst. interface.
|
||||
* Since we apply checks only on input pkts we use NULL.
|
||||
* The firewall knows this is a bridged packet as the cookie ptr
|
||||
* is NULL.
|
||||
*/
|
||||
if (IPFW_LOADED && bdg_ipfw != 0) {
|
||||
i = ip_fw_chk_ptr(&ip, 0, NULL, NULL /* cookie */, &m0, &rule, NULL);
|
||||
if ( (i & IP_FW_PORT_DENY_FLAG) || m0 == NULL) /* drop */
|
||||
return m0 ;
|
||||
} else
|
||||
i = 0; /* Treat it as a "pass" when not using ipfw. */
|
||||
|
||||
/*
|
||||
* If we get here, the firewall has passed the pkt, but the mbuf
|
||||
* pointer might have changed. Restore ip and the fields ntohs()'d.
|
||||
*/
|
||||
ip = mtod(m0, struct ip *);
|
||||
ip->ip_len = htons(ip->ip_len);
|
||||
ip->ip_off = htons(ip->ip_off);
|
||||
if (!IPFW_LOADED || bdg_ipfw == 0)
|
||||
goto forward; /* not using ipfw, accept the packet */
|
||||
i = ip_fw_chk_ptr(&m0, NULL, NULL /* cookie */, &rule,
|
||||
(struct sockaddr_in **)&save_eh);
|
||||
if ( (i & IP_FW_PORT_DENY_FLAG) || m0 == NULL) /* drop */
|
||||
return m0 ;
|
||||
|
||||
if (i == 0) /* a PASS rule. */
|
||||
goto forward ;
|
||||
|
|
|
@ -222,16 +222,13 @@ static __inline int
|
|||
int range_flag, int mask);
|
||||
static int tcpflg_match (struct tcphdr *tcp, struct ip_fw *f);
|
||||
static int icmptype_match (struct icmp * icmp, struct ip_fw * f);
|
||||
static void ipfw_report (struct ip_fw *f, struct ip *ip, int offset,
|
||||
static void ipfw_report (struct ip_fw *f, struct ip *ip, int ip_off,
|
||||
int ip_len, struct ifnet *rif,
|
||||
struct ifnet *oif);
|
||||
|
||||
static void flush_rule_ptrs(void);
|
||||
|
||||
static int ip_fw_chk (struct ip **pip, int hlen,
|
||||
struct ifnet *oif, u_int16_t *cookie, struct mbuf **m,
|
||||
struct ip_fw **flow_id,
|
||||
struct sockaddr_in **next_hop);
|
||||
static ip_fw_chk_t ip_fw_chk;
|
||||
static int ip_fw_ctl (struct sockopt *sopt);
|
||||
|
||||
ip_dn_ruledel_t *ip_dn_ruledel_ptr = NULL;
|
||||
|
@ -509,7 +506,7 @@ iface_match(struct ifnet *ifp, union ip_fw_if *ifu, int byname)
|
|||
}
|
||||
|
||||
static void
|
||||
ipfw_report(struct ip_fw *f, struct ip *ip, int offset, int ip_len,
|
||||
ipfw_report(struct ip_fw *f, struct ip *ip, int ip_off, int ip_len,
|
||||
struct ifnet *rif, struct ifnet *oif)
|
||||
{
|
||||
struct tcphdr *const tcp = (struct tcphdr *) ((u_int32_t *) ip+ ip->ip_hl);
|
||||
|
@ -519,6 +516,7 @@ ipfw_report(struct ip_fw *f, struct ip *ip, int offset, int ip_len,
|
|||
char *action;
|
||||
char action2[32], proto[47], name[18], fragment[27];
|
||||
int len;
|
||||
int offset = ip_off & IP_OFFMASK;
|
||||
|
||||
count = f ? f->fw_pcnt : ++counter;
|
||||
if ((f == NULL && fw_verbose_limit != 0 && count > fw_verbose_limit) ||
|
||||
|
@ -634,11 +632,11 @@ ipfw_report(struct ip_fw *f, struct ip *ip, int offset, int ip_len,
|
|||
break;
|
||||
}
|
||||
|
||||
if (ip->ip_off & (IP_MF | IP_OFFMASK))
|
||||
if (ip_off & (IP_MF | IP_OFFMASK))
|
||||
snprintf(SNPARGS(fragment, 0), " (frag %d:%d@%d%s)",
|
||||
ntohs(ip->ip_id), ip_len - (ip->ip_hl << 2),
|
||||
offset << 3,
|
||||
(ip->ip_off & IP_MF) ? "+" : "");
|
||||
(ip_off & IP_MF) ? "+" : "");
|
||||
else
|
||||
fragment[0] = '\0';
|
||||
if (oif)
|
||||
|
@ -1061,15 +1059,14 @@ lookup_next_rule(struct ip_fw *me)
|
|||
/*
|
||||
* Parameters:
|
||||
*
|
||||
* pip Pointer to packet header (struct ip **)
|
||||
* hlen Packet header length
|
||||
* *m The packet; we set to NULL when/if we nuke it.
|
||||
* oif Outgoing interface, or NULL if packet is incoming
|
||||
* *cookie Skip up to the first rule past this rule number;
|
||||
* upon return, non-zero port number for divert or tee.
|
||||
* Special case: cookie == NULL on input for bridging.
|
||||
* *m The packet; we set to NULL when/if we nuke it.
|
||||
* *flow_id pointer to the last matching rule (in/out)
|
||||
* *next_hop socket we are forwarding to (in/out).
|
||||
* For bridged packets, this is a pointer to the MAC header.
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
|
@ -1087,32 +1084,38 @@ lookup_next_rule(struct ip_fw *me)
|
|||
*/
|
||||
|
||||
static int
|
||||
ip_fw_chk(struct ip **pip, int hlen,
|
||||
struct ifnet *oif, u_int16_t *cookie, struct mbuf **m,
|
||||
struct ip_fw **flow_id,
|
||||
struct sockaddr_in **next_hop)
|
||||
ip_fw_chk(struct mbuf **m, struct ifnet *oif, u_int16_t *cookie,
|
||||
struct ip_fw **flow_id, struct sockaddr_in **next_hop)
|
||||
{
|
||||
struct ip_fw *f = NULL; /* matching rule */
|
||||
struct ip *ip = *pip;
|
||||
struct ip *ip = mtod(*m, struct ip *);
|
||||
struct ifnet *const rif = (*m)->m_pkthdr.rcvif;
|
||||
struct ifnet *tif;
|
||||
u_int hlen = ip->ip_hl << 2;
|
||||
struct ether_header * eh = NULL;
|
||||
|
||||
u_short offset = 0 ;
|
||||
u_short ip_off=0, offset = 0 ;
|
||||
/* local copy of addresses for faster matching */
|
||||
u_short src_port = 0, dst_port = 0;
|
||||
struct in_addr src_ip, dst_ip; /* XXX */
|
||||
u_int8_t proto= 0, flags = 0 ; /* XXX */
|
||||
struct in_addr src_ip, dst_ip;
|
||||
u_int8_t proto= 0, flags = 0;
|
||||
|
||||
u_int16_t skipto, bridgeCookie;
|
||||
u_int16_t ip_len;
|
||||
u_int16_t ip_len=0;
|
||||
|
||||
int dyn_checked = 0 ; /* set after dyn.rules have been checked. */
|
||||
int direction = MATCH_FORWARD ; /* dirty trick... */
|
||||
struct ipfw_dyn_rule *q = NULL ;
|
||||
|
||||
/* Special hack for bridging (as usual) */
|
||||
if (cookie == NULL) {
|
||||
#define BRIDGED (cookie == &bridgeCookie)
|
||||
if (cookie == NULL) { /* this is a bridged packet */
|
||||
bridgeCookie = 0;
|
||||
cookie = &bridgeCookie;
|
||||
#define BRIDGED (cookie == &bridgeCookie)
|
||||
eh = (struct ether_header *)next_hop;
|
||||
if ( (*m)->m_pkthdr.len >= sizeof(struct ip) &&
|
||||
ntohs(eh->ether_type) == ETHERTYPE_IP)
|
||||
hlen = ip->ip_hl << 2;
|
||||
} else {
|
||||
hlen = ip->ip_hl << 2;
|
||||
}
|
||||
|
||||
|
@ -1120,63 +1123,67 @@ ip_fw_chk(struct ip **pip, int hlen,
|
|||
skipto = *cookie;
|
||||
*cookie = 0;
|
||||
|
||||
#define PULLUP_TO(len) do { \
|
||||
if ((*m)->m_len < (len)) { \
|
||||
ip = NULL ; \
|
||||
if ((*m = m_pullup(*m, (len))) == 0) \
|
||||
goto bogusfrag; \
|
||||
ip = mtod(*m, struct ip *); \
|
||||
*pip = ip; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Collect parameters into local variables for faster matching.
|
||||
*/
|
||||
proto = ip->ip_p;
|
||||
src_ip = ip->ip_src;
|
||||
dst_ip = ip->ip_dst;
|
||||
if (0 && BRIDGED) { /* not yet... */
|
||||
offset = (ntohs(ip->ip_off) & IP_OFFMASK);
|
||||
ip_len = ntohs(ip->ip_len);
|
||||
} else {
|
||||
offset = (ip->ip_off & IP_OFFMASK);
|
||||
ip_len = ip->ip_len;
|
||||
}
|
||||
if (offset == 0) {
|
||||
switch (proto) {
|
||||
case IPPROTO_TCP : {
|
||||
struct tcphdr *tcp;
|
||||
if (hlen > 0) { /* this is an IP packet */
|
||||
proto = ip->ip_p;
|
||||
src_ip = ip->ip_src;
|
||||
dst_ip = ip->ip_dst;
|
||||
if (BRIDGED) { /* not yet... */
|
||||
ip_off = ntohs(ip->ip_off);
|
||||
ip_len = ntohs(ip->ip_len);
|
||||
} else {
|
||||
ip_off = ip->ip_off;
|
||||
ip_len = ip->ip_len;
|
||||
}
|
||||
offset = ip_off & IP_OFFMASK;
|
||||
if (offset == 0) {
|
||||
|
||||
PULLUP_TO(hlen + sizeof(struct tcphdr));
|
||||
tcp =(struct tcphdr *)((u_int32_t *)ip + ip->ip_hl);
|
||||
dst_port = tcp->th_dport ;
|
||||
src_port = tcp->th_sport ;
|
||||
flags = tcp->th_flags ;
|
||||
#define PULLUP_TO(len) \
|
||||
do { \
|
||||
if ((*m)->m_len < (len)) { \
|
||||
*m = m_pullup(*m, (len)); \
|
||||
if (*m == 0) \
|
||||
goto bogusfrag; \
|
||||
ip = mtod(*m, struct ip *); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
switch (proto) {
|
||||
case IPPROTO_TCP : {
|
||||
struct tcphdr *tcp;
|
||||
|
||||
PULLUP_TO(hlen + sizeof(struct tcphdr));
|
||||
tcp =(struct tcphdr *)((u_int32_t *)ip + ip->ip_hl);
|
||||
dst_port = tcp->th_dport ;
|
||||
src_port = tcp->th_sport ;
|
||||
flags = tcp->th_flags ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case IPPROTO_UDP : {
|
||||
struct udphdr *udp;
|
||||
|
||||
PULLUP_TO(hlen + sizeof(struct udphdr));
|
||||
udp =(struct udphdr *)((u_int32_t *)ip + ip->ip_hl);
|
||||
dst_port = udp->uh_dport ;
|
||||
src_port = udp->uh_sport ;
|
||||
}
|
||||
break;
|
||||
|
||||
case IPPROTO_ICMP:
|
||||
PULLUP_TO(hlen + 4); /* type, code and checksum. */
|
||||
flags = ((struct icmp *)
|
||||
((u_int32_t *)ip + ip->ip_hl))->icmp_type ;
|
||||
break ;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
break ;
|
||||
|
||||
case IPPROTO_UDP : {
|
||||
struct udphdr *udp;
|
||||
|
||||
PULLUP_TO(hlen + sizeof(struct udphdr));
|
||||
udp =(struct udphdr *)((u_int32_t *)ip + ip->ip_hl);
|
||||
dst_port = udp->uh_dport ;
|
||||
src_port = udp->uh_sport ;
|
||||
}
|
||||
break;
|
||||
|
||||
case IPPROTO_ICMP:
|
||||
PULLUP_TO(hlen + 4); /* type, code and checksum. */
|
||||
flags = ((struct icmp *)
|
||||
((u_int32_t *)ip + ip->ip_hl))->icmp_type ;
|
||||
break ;
|
||||
|
||||
default :
|
||||
break;
|
||||
#undef PULLUP_TO
|
||||
}
|
||||
}
|
||||
#undef PULLUP_TO
|
||||
last_pkt.src_ip = ntohl(src_ip.s_addr);
|
||||
last_pkt.dst_ip = ntohl(dst_ip.s_addr);
|
||||
last_pkt.proto = proto;
|
||||
|
@ -1471,8 +1478,8 @@ ip_fw_chk(struct ip **pip, int hlen,
|
|||
|
||||
bogusfrag:
|
||||
if (fw_verbose) {
|
||||
if (ip != NULL)
|
||||
ipfw_report(NULL, ip, offset, ip_len, rif, oif);
|
||||
if (*m != NULL)
|
||||
ipfw_report(NULL, ip, ip_off, ip_len, rif, oif);
|
||||
else
|
||||
printf("pullup failed\n");
|
||||
}
|
||||
|
@ -1498,8 +1505,8 @@ ip_fw_chk(struct ip **pip, int hlen,
|
|||
f->timestamp = time_second;
|
||||
|
||||
/* Log to console if desired */
|
||||
if ((f->fw_flg & IP_FW_F_PRN) && fw_verbose)
|
||||
ipfw_report(f, ip, offset, ip_len, rif, oif);
|
||||
if ((f->fw_flg & IP_FW_F_PRN) && fw_verbose && hlen >0)
|
||||
ipfw_report(f, ip, ip_off, ip_len, rif, oif);
|
||||
|
||||
/* Take appropriate action */
|
||||
switch (f->fw_flg & IP_FW_F_COMMAND) {
|
||||
|
|
|
@ -49,11 +49,26 @@ union ip_fw_if {
|
|||
* Port numbers are stored in HOST byte order.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To match MAC headers:
|
||||
* 12 bytes at fw_mac_hdr contain the dst-src MAC address after masking.
|
||||
* 12 bytes at fw_mac_mask contain the mask to apply to dst-src
|
||||
* 2 bytes at fw_mac_type contain the mac type after mask (in net format)
|
||||
* 2 bytes at fw_mac_type_mask contain the mac type mask
|
||||
* If IP_FW_F_SRNG, the two contain the low-high of a range of types.
|
||||
* IP_FW_F_DRNG is used to indicare we want to match a vlan.
|
||||
*/
|
||||
#define fw_mac_hdr fw_src
|
||||
#define fw_mac_mask fw_uar
|
||||
#define fw_mac_type fw_iplen
|
||||
#define fw_mac_mask_type fw_ipid
|
||||
|
||||
struct ip_fw {
|
||||
LIST_ENTRY(ip_fw) next; /* bidirectional list of rules */
|
||||
u_int fw_flg; /* Operational Flags word */
|
||||
u_int64_t fw_pcnt; /* Packet counters */
|
||||
u_int64_t fw_bcnt; /* Byte counters */
|
||||
|
||||
struct in_addr fw_src; /* Source IP address */
|
||||
struct in_addr fw_dst; /* Destination IP address */
|
||||
struct in_addr fw_smsk; /* Mask for source IP address */
|
||||
|
@ -238,8 +253,9 @@ struct ipfw_dyn_rule {
|
|||
#define IP_FW_F_CHECK_S 0x10000000 /* check state */
|
||||
#define IP_FW_F_SME 0x20000000 /* source = me */
|
||||
#define IP_FW_F_DME 0x40000000 /* destination = me */
|
||||
#define IP_FW_F_MAC 0x80000000 /* match MAC header */
|
||||
|
||||
#define IP_FW_F_MASK 0x7FFFFFFF /* All possible flag bits mask */
|
||||
#define IP_FW_F_MASK 0xFFFFFFFF /* All possible flag bits mask */
|
||||
|
||||
/*
|
||||
* Flags for the 'fw_ipflg' field, for comparing values
|
||||
|
@ -320,8 +336,8 @@ void ip_fw_init(void);
|
|||
/* Firewall hooks */
|
||||
struct ip;
|
||||
struct sockopt;
|
||||
typedef int ip_fw_chk_t (struct ip **, int, struct ifnet *, u_int16_t *,
|
||||
struct mbuf **, struct ip_fw **, struct sockaddr_in **);
|
||||
typedef int ip_fw_chk_t (struct mbuf **m, struct ifnet *oif,
|
||||
u_int16_t *cookie, struct ip_fw **rule, struct sockaddr_in **next_hop);
|
||||
typedef int ip_fw_ctl_t (struct sockopt *);
|
||||
extern ip_fw_chk_t *ip_fw_chk_ptr;
|
||||
extern ip_fw_ctl_t *ip_fw_ctl_ptr;
|
||||
|
|
|
@ -450,22 +450,14 @@ ip_input(struct mbuf *m)
|
|||
* See the comment in ip_output for the return values
|
||||
* produced by the firewall.
|
||||
*/
|
||||
i = ip_fw_chk_ptr(&ip, hlen, NULL,
|
||||
&divert_cookie, &m, &rule, &ip_fw_fwd_addr);
|
||||
if (i & IP_FW_PORT_DENY_FLAG) { /* XXX new interface-denied */
|
||||
i = ip_fw_chk_ptr(&m, NULL /* oif */, &divert_cookie,
|
||||
&rule, &ip_fw_fwd_addr);
|
||||
if ( (i & IP_FW_PORT_DENY_FLAG) || m == NULL) { /* drop */
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
if (m == NULL) { /* Packet discarded by firewall */
|
||||
static int __debug=10;
|
||||
if (__debug > 0) {
|
||||
printf(
|
||||
"firewall returns NULL, please update!\n");
|
||||
__debug--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
ip = mtod(m, struct ip *); /* just in case m changed */
|
||||
if (i == 0 && ip_fw_fwd_addr == NULL) /* common case */
|
||||
goto pass;
|
||||
if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG) != 0) {
|
||||
|
|
|
@ -610,8 +610,7 @@ ip_output(m0, opt, ro, flags, imo)
|
|||
if (fw_enable && IPFW_LOADED && !ip_fw_fwd_addr) {
|
||||
struct sockaddr_in *old = dst;
|
||||
|
||||
off = ip_fw_chk_ptr(&ip,
|
||||
hlen, ifp, &divert_cookie, &m, &rule, &dst);
|
||||
off = ip_fw_chk_ptr(&m, ifp, &divert_cookie, &rule, &dst);
|
||||
/*
|
||||
* On return we must do the following:
|
||||
* m == NULL -> drop the pkt (old interface, deprecated)
|
||||
|
@ -627,23 +626,13 @@ ip_output(m0, opt, ro, flags, imo)
|
|||
* unsupported rules), but better play safe and drop
|
||||
* packets in case of doubt.
|
||||
*/
|
||||
if (off & IP_FW_PORT_DENY_FLAG) { /* XXX new interface-denied */
|
||||
if ( (off & IP_FW_PORT_DENY_FLAG) || m == NULL) {
|
||||
if (m)
|
||||
m_freem(m);
|
||||
error = EACCES;
|
||||
goto done;
|
||||
}
|
||||
if (!m) { /* firewall said to reject */
|
||||
static int __debug=10;
|
||||
|
||||
if (__debug > 0) {
|
||||
printf(
|
||||
"firewall returns NULL, please update!\n");
|
||||
__debug--;
|
||||
}
|
||||
error = EACCES;
|
||||
goto done;
|
||||
}
|
||||
ip = mtod(m, struct ip *);
|
||||
if (off == 0 && dst == old) /* common case */
|
||||
goto pass;
|
||||
if (DUMMYNET_LOADED && (off & IP_FW_PORT_DYNT_FLAG) != 0) {
|
||||
|
|
Loading…
Reference in a new issue