diff options
author | luigi <luigi@FreeBSD.org> | 2001-01-26 06:49:34 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2001-01-26 06:49:34 +0000 |
commit | 8a9237833ebf0bb18cda25808491747b7f159304 (patch) | |
tree | 457b6a4db248b0f3ce57eea6c82b8f31c4489c47 /sys | |
parent | f9659c70dd2db81588a25ff084e8456958695e85 (diff) | |
download | FreeBSD-src-8a9237833ebf0bb18cda25808491747b7f159304.zip FreeBSD-src-8a9237833ebf0bb18cda25808491747b7f159304.tar.gz |
Bring dummynet in line with the code that now works in -STABLE.
It compiles, but I cannot test functionality yet.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/ip_dummynet.c | 213 | ||||
-rw-r--r-- | sys/netinet/ip_fw.c | 80 |
2 files changed, 164 insertions, 129 deletions
diff --git a/sys/netinet/ip_dummynet.c b/sys/netinet/ip_dummynet.c index a17b09f..366d447 100644 --- a/sys/netinet/ip_dummynet.c +++ b/sys/netinet/ip_dummynet.c @@ -47,8 +47,9 @@ * * Most important Changes: * + * 010124: Fixed WF2Q behaviour * 010122: Fixed spl protection. - * 000601: WF2Q+ support + * 000601: WF2Q support * 000106: large rewrite, use heaps to handle very many pipes. * 980513: initial release * @@ -92,7 +93,7 @@ static int dn_hash_size = 64 ; /* default hash size */ /* statistics on number of queue searches and search steps */ static int searches, search_steps ; -static int pipe_expire = 0 ; /* expire queue if empty */ +static int pipe_expire = 1 ; /* expire queue if empty */ static int dn_max_ratio = 16 ; /* max queues/buckets ratio */ static int red_lookup_depth = 256; /* RED - default lookup table depth */ @@ -100,16 +101,21 @@ static int red_avg_pkt_size = 512; /* RED - default medium packet size */ static int red_max_pkt_size = 1500; /* RED - default max packet size */ /* - * ready_heap contains all dn_flow_queue's scheduled for action - * at a given time. - * wfq_ready_heap contains the schedulable pipe. - * Extract_heap contains pipes because it is there that packets - * in the delay line are held. + * Three heaps contain queues and pipes that the scheduler handles: + * + * ready_heap contains all dn_flow_queue related to fixed-rate pipes. + * + * wfq_ready_heap contains the pipes associated with WF2Q flows + * + * extract_heap contains pipes associated with delay lines. + * */ static struct dn_heap ready_heap, extract_heap, wfq_ready_heap ; + static int heap_init(struct dn_heap *h, int size) ; static int heap_insert (struct dn_heap *h, dn_key key1, void *p); static void heap_extract(struct dn_heap *h, void *obj); + static void transmit_event(struct dn_pipe *pipe); static void ready_event(struct dn_flow_queue *q); @@ -152,6 +158,8 @@ static void dummynet(void *); static void dummynet_flush(void); void dummynet_drain(void); +int if_tx_rdy(struct ifnet *ifp); + /* * ip_fw_chain is used when deleting a pipe, because ipfw rules can * hold references to the pipe. @@ -270,22 +278,22 @@ heap_extract(struct dn_heap *h, void *obj) { int child, father, max = h->elements - 1 ; - if (max < 0) + if (max < 0) { + printf("warning, extract from empty heap 0x%p\n", h); return ; + } father = 0 ; /* default: move up smallest child */ if (obj != NULL) { /* extract specific element, index is at offset */ - if (h->offset <= 0) { - printf("*** extract from middle not supported!!!\n"); - return ; /* or maybe panic... */ - } + if (h->offset <= 0) + panic("*** heap_extract from middle not supported on this heap!!!\n"); father = *((int *)((char *)obj + h->offset)) ; if (father < 0 || father >= h->elements) { printf("dummynet: heap_extract, father %d out of bound 0..%d\n", father, h->elements); panic("heap_extract"); } - RESET_OFFSET(h, father); } + RESET_OFFSET(h, father); child = HEAP_LEFT(father) ; /* left child */ while (child <= max) { /* valid entry */ if (child != max && DN_KEY_LT(h->p[child+1].key, h->p[child].key) ) @@ -302,7 +310,7 @@ heap_extract(struct dn_heap *h, void *obj) */ h->p[father] = h->p[max] ; heap_insert(h, father, NULL); /* this one cannot fail */ - } + } } /* @@ -343,8 +351,6 @@ heap_move(struct dn_heap *h, dn_key new_key, void *object) SET_OFFSET(h, i); } - - /* * heapify() will reorganize data inside an array to maintain the * heap property. It is needed when we delete a bunch of entries. @@ -366,7 +372,7 @@ heap_free(struct dn_heap *h) { if (h->size >0 ) free(h->p, M_IPFW); - h->elements = h->size = 0 ; + bzero(h, sizeof(*h) ); } /* @@ -384,7 +390,7 @@ heap_free(struct dn_heap *h) * ready_event() does something similar with fixed-rate queues, and the * event handled is the finish time of the head pkt. * - * wfq_ready_event() does something similar with WFQ queues, and the + * wfq_ready_event() does something similar with WF2Q queues, and the * event handled is the start time of the head pkt. * * In all cases, we make sure that the data structures are consistent @@ -426,14 +432,17 @@ transmit_event(struct dn_pipe *pipe) #ifdef BRIDGE case DN_TO_BDG_FWD : { struct mbuf *m = (struct mbuf *)pkt; - struct ether_header hdr; + struct ether_header *eh; if (pkt->dn_m->m_len < ETHER_HDR_LEN && (pkt->dn_m = m_pullup(pkt->dn_m, ETHER_HDR_LEN)) == NULL) { printf("dummynet/bridge: pullup fail, dropping pkt\n"); break; } - bcopy(mtod(pkt->dn_m, struct ether_header *), &hdr, ETHER_HDR_LEN); + /* + * same as ether_input, make eh be a pointer into the mbuf + */ + eh = (void *)pkt->dn_m->m_data ; m_adj(pkt->dn_m, ETHER_HDR_LEN); /* * bdg_forward() wants a pointer to the pseudo-mbuf-header, but @@ -441,7 +450,7 @@ transmit_event(struct dn_pipe *pipe) * (originally pkt->dn_m, but could be something else now) if * it has not consumed it. */ - bdg_forward(&m, &hdr, pkt->ifp); + bdg_forward(&m, eh, pkt->ifp); if (m) m_freem(m); } @@ -569,6 +578,7 @@ ready_event_wfq(struct dn_pipe *p) int p_was_empty = (p->head == NULL) ; struct dn_heap *sch = &(p->scheduler_heap); struct dn_heap *blh = &(p->backlogged_heap); + struct dn_heap *neh = &(p->not_eligible_heap) ; if (p->if_name[0] == 0) /* tx clock is simulated */ p->numbytes += ( curr_time - p->sched_time ) * p->bandwidth; @@ -581,64 +591,71 @@ ready_event_wfq(struct dn_pipe *p) } } - while ( sch->elements && p->numbytes >= 0 ) { - struct dn_heap *neh ; - u_int64_t normalized_service ; - struct dn_flow_queue *q = sch->p[0].object ; - struct dn_pkt *pkt = q->head; - struct dn_flow_set *fs = q->fs; - u_int64_t len = pkt->dn_m->m_pkthdr.len; - int len_scaled = p->bandwidth ? len*8*hz : 0 ; - - heap_extract(sch, NULL); /* remove queue from heap */ - p->numbytes -= len_scaled ; - move_pkt(pkt, q, p, len); - - /* XXX should we do this at the end of the service ? */ - /* evaluate normalized service */ - normalized_service = (len<<MY_M)/p->sum ; - q->S = q->F ; /* update start time */ - if (q->len == 0) { - /* - * Session not backlogged any more, remove from backlogged - * and insert into idle_heap - */ - heap_extract(blh, q); - fs->backlogged-- ; - /* p->sum -= fs->weight; XXX don't do this here ! */ - heap_insert(&(p->idle_heap), q->F, q); - } else { /* session backlogged again: update values */ - len = (q->head)->dn_m->m_pkthdr.len; - q->F += (len<<MY_M)/(u_int64_t) fs->weight ; - /* update queue position in backlogged_heap */ - heap_move(blh, q->S, q); + /* + * While we have backlogged traffic AND credit, we need to do + * something on the queue. + */ + while ( blh->elements>0 && p->numbytes >= 0 ) { + if (sch->elements > 0) { /* have some eligible pkts to send out */ + struct dn_flow_queue *q = sch->p[0].object ; + struct dn_pkt *pkt = q->head; + struct dn_flow_set *fs = q->fs; + u_int64_t len = pkt->dn_m->m_pkthdr.len; + int len_scaled = p->bandwidth ? len*8*hz : 0 ; + + heap_extract(sch, NULL); /* remove queue from heap */ + p->numbytes -= len_scaled ; + move_pkt(pkt, q, p, len); + + p->V += (len<<MY_M) / p->sum ; /* update V */ + q->S = q->F ; /* update start time */ + if (q->len == 0) { /* Flow not backlogged any more */ + heap_extract(blh, q); + fs->backlogged-- ; + heap_insert(&(p->idle_heap), q->F, q); + } else { /* still backlogged */ + /* + * update F and position in backlogged queue, then + * put flow in not_eligible_heap (we will fix this later). + */ + len = (q->head)->dn_m->m_pkthdr.len; + q->F += (len<<MY_M)/(u_int64_t) fs->weight ; + heap_move(blh, q->S, q); + heap_insert(neh, q->S, q); + } } - /* update virtual time */ - p->V += normalized_service ; if (blh->elements > 0) p->V = MAX64 ( p->V, blh->p[0].key ); - DEB(printf("-- %d backlogged, V is %d\n", - blh->elements, (int)(p->V >> MY_M) ); ) - /* move from not_eligible_heap to scheduler_heap */ neh = &(p->not_eligible_heap) ; while (neh->elements > 0 && DN_KEY_LEQ(neh->p[0].key, p->V) ) { - struct dn_flow_queue *temp = neh->p[0].object ; + struct dn_flow_queue *q = neh->p[0].object ; heap_extract(neh, NULL); - heap_insert(sch, temp->F, temp); + heap_insert(sch, q->F, q); } - if (q->len) {/* need to reschedule queue */ - if ( DN_KEY_LEQ(q->S, p->V) ) - heap_insert(sch, q->F, q); /* schedule following packet */ - else - heap_insert(neh, q->S, q); /* queue in not_eligible_heap */ - } if (p->if_name[0] != '\0') {/* tx clock is from a real thing */ p->numbytes = -1 ; /* mark not ready for I/O */ break ; } } + if (blh->elements == 0 && p->numbytes >= 0 && p->idle_heap.elements > 0) { + /* + * no traffic and no events scheduled. We can get rid of idle-heap. + */ + int i ; + + for (i = 0 ; i < p->idle_heap.elements ; i++) { + struct dn_flow_queue *q = p->idle_heap.p[i].object ; + + q->F = 0 ; + q->S = q->F + 1 ; + } + p->sum = 0 ; + p->V = 0 ; + p->idle_heap.elements = 0 ; + } + /* * If we are getting clocks from dummynet (not a real interface) and * If we are under credit, schedule the next ready event. @@ -745,6 +762,7 @@ if_tx_rdy(struct ifnet *ifp) p->numbytes = 0 ; /* mark ready for I/O */ ready_event_wfq(p); } + return 0 ; } /* @@ -762,7 +780,7 @@ expire_queues(struct dn_flow_set *fs) fs->last_expired = time_second ; for (i = 0 ; i <= fs->rq_size ; i++) /* last one is overflow */ for (prev=NULL, q = fs->rq[i] ; q != NULL ; ) - if (q->head != NULL) { + if (q->head != NULL || q->S != q->F+1) { prev = q ; q = q->next ; } else { /* entry is idle, expire it */ @@ -845,8 +863,8 @@ find_queue(struct dn_flow_set *fs) search_steps++; if (bcmp(&last_pkt, &(q->id), sizeof(q->id) ) == 0) break ; /* found */ - else if (pipe_expire && q->head == NULL) { - /* entry is idle, expire it */ + else if (pipe_expire && q->head == NULL && q->S == q->F+1 ) { + /* entry is idle and not in any heap, expire it */ struct dn_flow_queue *old_q = q ; if (prev != NULL) @@ -1017,6 +1035,7 @@ dummynet_io(int pipe_nr, int dir, /* pipe_nr can also be a fs_nr */ s = splimp(); pipe_nr &= 0xffff ; + if ( (fs = rule->rule->pipe_ptr) == NULL ) { fs = locate_flowset(pipe_nr, rule); if (fs == NULL) @@ -1033,7 +1052,7 @@ dummynet_io(int pipe_nr, int dir, /* pipe_nr can also be a fs_nr */ printf("No pipe %d for queue %d, drop pkt\n", fs->parent_nr, fs->fs_nr); goto dropit ; - } + } } q = find_queue(fs); if ( q == NULL ) @@ -1095,28 +1114,34 @@ dummynet_io(int pipe_nr, int dir, /* pipe_nr can also be a fs_nr */ static int errors = 0 ; if (q->blh_pos >= 0 ) /* good... */ goto done; - printf("+++ hey [%d] flow 0x%08x not idle but not in heap\n", + printf("+++ hey [%d] flow 0x%8p not idle but not in heap\n", ++errors, q); } /* - * The flow was previously idle, so we need to schedule it. + * If we reach this point the flow was previously idle, so we need + * to schedule it. This involves different actions for fixed-rate or + * WF2Q queues. */ if ( (rule->rule->fw_flg & IP_FW_F_COMMAND) == IP_FW_F_PIPE ) { - /* fixed-rate queue: just insert into the ready_heap. */ + /* + * Fixed-rate queue: just insert into the ready_heap. + */ dn_key t = 0 ; if (pipe->bandwidth) t = SET_TICKS(pkt, q, pipe); q->sched_time = curr_time ; if (t == 0) /* must process it now */ - ready_event( q ); + ready_event( q ); else heap_insert(&ready_heap, curr_time + t , q ); } else { /* - * WF2Q: compute start time and put into backlogged list. Then - * look at eligibility -- if not eligibile, it means that - * there is some other flow already scheduled for the same pipe. - * If eligible, AND the pipe is idle, then call ready_event_wfq(). + * WF2Q: first compute start time S. If the flow was not in the + * idle_heap (denoted by S=F+1), S is set to the virtual time V + * for that pipe, and we update the sum of weights for the pipe. + * Otherwise, remove flow from idle_heap and set S to max(F,V). + * Then compute finish time F = S + len/weight, and insert into + * backlogged_heap according to S. */ if (DN_KEY_GT(q->S, q->F)) { /* means timestamps are invalid */ q->S = pipe->V ; @@ -1129,8 +1154,20 @@ dummynet_io(int pipe_nr, int dir, /* pipe_nr can also be a fs_nr */ heap_insert(&(pipe->backlogged_heap), q->S, q); fs->backlogged++ ; + if (pipe->backlogged_heap.elements == 1) + pipe->V = MAX64 ( q->S, pipe->V ); + /* + * Look at eligibility. A flow is not eligibile if S>V (when + * this happens, it means that there is some other flow already + * scheduled for the same pipe, so the scheduler_heap cannot be + * empty). If the flow is not eligible we just store it in the + * appropriate heap. Otherwise, we store in the scheduler_heap + * and possibly invoke ready_event_wfq() right now if there is + * leftover credit. + */ if (DN_KEY_GT(q->S, pipe->V) ) { /* not eligible */ - DDB(printf("== not eligible, size %d\n", (int)len);) + if (pipe->scheduler_heap.elements == 0) + printf("++ ouch! not eligible but empty scheduler!\n"); heap_insert(&(pipe->not_eligible_heap), q->S, q); } else { heap_insert(&(pipe->scheduler_heap), q->F, q); @@ -1153,7 +1190,7 @@ dropit: if (q) q->drops++ ; m_freem(m); - return 0 ; /* XXX should I return an error ? */ + return ENOBUFS ; } /* @@ -1524,10 +1561,10 @@ config_pipe(struct dn_pipe *p) return 0 ; } - /* +/* * Helper function to remove from a heap queues which are linked to * a flow_set about to be deleted. - */ +*/ static void fs_remove_from_heap(struct dn_heap *h, struct dn_flow_set *fs) { @@ -1553,9 +1590,9 @@ pipe_remove_from_heap(struct dn_heap *h, struct dn_pipe *p) int i = 0 ; for (i=0; i < h->elements ; i++ ) { if (h->p[i].object == p) { /* found it */ - h->elements-- ; - h->p[i] = h->p[h->elements] ; - heapify(h); + h->elements-- ; + h->p[i] = h->p[h->elements] ; + heapify(h); break ; } } @@ -1635,8 +1672,8 @@ delete_pipe(struct dn_pipe *p) /* remove reference to here from extract_heap and wfq_ready_heap */ pipe_remove_from_heap(&extract_heap, b); pipe_remove_from_heap(&wfq_ready_heap, b); - splx(s); - free(b, M_IPFW); + splx(s); + free(b, M_IPFW); } else { /* this is a dummynet queue (dn_flow_set) */ struct dn_flow_set *a, *b; @@ -1662,7 +1699,7 @@ delete_pipe(struct dn_pipe *p) fs_remove_from_heap(&(b->pipe->backlogged_heap), b); fs_remove_from_heap(&(b->pipe->not_eligible_heap), b); fs_remove_from_heap(&(b->pipe->scheduler_heap), b); -#if 0 /* XXX should i remove from idle_heap as well ? */ +#if 1 /* XXX should i remove from idle_heap as well ? */ fs_remove_from_heap(&(b->pipe->idle_heap), b); #endif } @@ -1817,7 +1854,7 @@ ip_dn_ctl(struct sockopt *sopt) static void ip_dn_init(void) { - printf("DUMMYNET initialized (010116)\n"); + printf("DUMMYNET initialized (010124)\n"); all_pipes = NULL ; all_flow_sets = NULL ; ready_heap.size = ready_heap.elements = 0 ; diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c index 3f3d325..0b86c74 100644 --- a/sys/netinet/ip_fw.c +++ b/sys/netinet/ip_fw.c @@ -78,6 +78,13 @@ static int fw_verbose_limit = IPFIREWALL_VERBOSE_LIMIT; static int fw_verbose_limit = 0; #endif +/* + * Right now, two fields in the IP header are changed to host format + * by the IP layer before calling the firewall. Ideally, we would like + * to have them in network format so that the packet can be + * used as it comes from the device driver (and is thus readonly). + */ + static u_int64_t counter; /* counter for ipfw_report(NULL...) */ struct ipfw_flow_id last_pkt ; @@ -102,7 +109,6 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose, CTLFLAG_RW, SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW, &fw_verbose_limit, 0, "Set upper limit of matches of ipfw rules logged"); -#if STATEFUL /* * Extension for stateful ipfw. * @@ -173,7 +179,6 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime, CTLFLAG_RW, &dyn_rst_lifetime, 0, "Lifetime of dyn. rules for rst"); SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime, CTLFLAG_RW, &dyn_short_lifetime, 0, "Lifetime of dyn. rules for other situations"); -#endif /* STATEFUL */ #endif @@ -198,7 +203,7 @@ static __inline int int range_flag, int mask)); static int tcpflg_match __P((struct tcphdr *tcp, struct ip_fw *f)); static int icmptype_match __P((struct icmp * icmp, struct ip_fw * f)); -static void ipfw_report __P((struct ip_fw *f, struct ip *ip, +static void ipfw_report __P((struct ip_fw *f, struct ip *ip, int offset, struct ifnet *rif, struct ifnet *oif)); static void flush_rule_ptrs(void); @@ -486,7 +491,7 @@ iface_match(struct ifnet *ifp, union ip_fw_if *ifu, int byname) } static void -ipfw_report(struct ip_fw *f, struct ip *ip, +ipfw_report(struct ip_fw *f, struct ip *ip, int offset, struct ifnet *rif, struct ifnet *oif) { struct tcphdr *const tcp = (struct tcphdr *) ((u_int32_t *) ip+ ip->ip_hl); @@ -571,33 +576,33 @@ ipfw_report(struct ip_fw *f, struct ip *ip, case IPPROTO_TCP: len = snprintf(SNPARGS(proto, 0), "TCP %s", inet_ntoa(ip->ip_src)); - if ((ip->ip_off & IP_OFFMASK) == 0) + if (offset == 0) len += snprintf(SNPARGS(proto, len), ":%d ", ntohs(tcp->th_sport)); else len += snprintf(SNPARGS(proto, len), " "); len += snprintf(SNPARGS(proto, len), "%s", inet_ntoa(ip->ip_dst)); - if ((ip->ip_off & IP_OFFMASK) == 0) + if (offset == 0) snprintf(SNPARGS(proto, len), ":%d", ntohs(tcp->th_dport)); break; case IPPROTO_UDP: len = snprintf(SNPARGS(proto, 0), "UDP %s", inet_ntoa(ip->ip_src)); - if ((ip->ip_off & IP_OFFMASK) == 0) + if (offset == 0) len += snprintf(SNPARGS(proto, len), ":%d ", ntohs(udp->uh_sport)); else len += snprintf(SNPARGS(proto, len), " "); len += snprintf(SNPARGS(proto, len), "%s", inet_ntoa(ip->ip_dst)); - if ((ip->ip_off & IP_OFFMASK) == 0) + if (offset == 0) snprintf(SNPARGS(proto, len), ":%d", ntohs(udp->uh_dport)); break; case IPPROTO_ICMP: - if ((ip->ip_off & IP_OFFMASK) == 0) + if (offset == 0) len = snprintf(SNPARGS(proto, 0), "ICMP:%u.%u ", icmp->icmp_type, icmp->icmp_code); else @@ -613,9 +618,9 @@ ipfw_report(struct ip_fw *f, struct ip *ip, break; } - if ((ip->ip_off & IP_OFFMASK)) + if (offset != 0) snprintf(SNPARGS(fragment, 0), " Fragment = %d", - ip->ip_off & IP_OFFMASK); + offset); else fragment[0] = '\0'; if (oif) @@ -635,7 +640,6 @@ ipfw_report(struct ip_fw *f, struct ip *ip, f ? f->fw_number : -1); } -#if STATEFUL static __inline int hash_packet(struct ipfw_flow_id *id) { @@ -883,7 +887,6 @@ install_state(struct ip_fw_chain *chain) } q = lookup_dyn_rule(&last_pkt, NULL) ; /* XXX this just sets the lifetime ... */ } -#endif /* STATEFUL */ /* * given an ip_fw_chain *, lookup_next_rule will return a pointer @@ -950,17 +953,18 @@ ip_fw_chk(struct ip **pip, int hlen, struct in_addr src_ip, dst_ip; /* XXX */ u_int8_t proto= 0, flags = 0 ; /* XXX */ u_int16_t skipto, bridgeCookie; + u_int16_t ip_len; -#if STATEFUL int dyn_checked = 0 ; /* set after dyn.rules have been checked. */ int direction = MATCH_FORWARD ; /* dirty trick... */ struct ipfw_dyn_rule *q = NULL ; -#endif /* Special hack for bridging (as usual) */ if (cookie == NULL) { bridgeCookie = 0; cookie = &bridgeCookie; +#define BRIDGED (cookie == &bridgeCookie) + hlen = ip->ip_hl << 2; } /* Grab and reset cookie */ @@ -982,7 +986,13 @@ ip_fw_chk(struct ip **pip, int hlen, proto = ip->ip_p; src_ip = ip->ip_src; dst_ip = ip->ip_dst; - offset = (ip->ip_off & IP_OFFMASK); + if (0 && BRIDGED) { + 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) { struct tcphdr *tcp; struct udphdr *udp; @@ -1059,7 +1069,6 @@ again: if (f->fw_number == IPFW_DEFAULT_RULE) goto got_match ; -#if STATEFUL /* * dynamic rules are checked at the first keep-state or * check-state occurrence. @@ -1076,17 +1085,16 @@ again: chain = q->chain ; f = chain->rule ; q->pcnt++ ; - q->bcnt += ip->ip_len; + q->bcnt += ip_len; goto got_match ; /* random not allowed here */ } /* if this was a check-only rule, continue with next */ if (f->fw_flg & IP_FW_F_CHECK_S) continue ; } -#endif /* stateful ipfw */ /* Check if rule only valid for bridged packets */ - if ((f->fw_flg & IP_FW_BRIDGED) != 0 && cookie != &bridgeCookie) + if ((f->fw_flg & IP_FW_BRIDGED) != 0 && ! (BRIDGED) ) continue; if (oif) { @@ -1137,7 +1145,7 @@ again: /* Check IP header values */ if (f->fw_ipflg & IP_FW_IF_IPOPT && !ipopts_match(ip, f)) continue; - if (f->fw_ipflg & IP_FW_IF_IPLEN && f->fw_iplen != ip->ip_len) + if (f->fw_ipflg & IP_FW_IF_IPLEN && f->fw_iplen != ip_len) continue; if (f->fw_ipflg & IP_FW_IF_IPID && f->fw_ipid != ntohs(ip->ip_id)) continue; @@ -1304,7 +1312,7 @@ check_ports: bogusfrag: if (fw_verbose) - ipfw_report(NULL, ip, rif, oif); + ipfw_report(NULL, ip, offset, rif, oif); goto dropit; } @@ -1314,23 +1322,21 @@ rnd_then_got_match: random() < ((struct ip_fw_ext *)f)->dont_match_prob ) continue ; got_match: -#if STATEFUL /* stateful ipfw */ /* * If not a dynamic match (q == NULL) and keep-state, install * a new dynamic entry. */ if (q == NULL && f->fw_flg & IP_FW_F_KEEP_S) install_state(chain); -#endif *flow_id = chain ; /* XXX set flow id */ /* Update statistics */ f->fw_pcnt += 1; - f->fw_bcnt += ip->ip_len; + f->fw_bcnt += ip_len; f->timestamp = time_second; /* Log to console if desired */ if ((f->fw_flg & IP_FW_F_PRN) && fw_verbose) - ipfw_report(f, ip, rif, oif); + ipfw_report(f, ip, offset, rif, oif); /* Take appropriate action */ switch (f->fw_flg & IP_FW_F_COMMAND) { @@ -1401,6 +1407,7 @@ got_match: switch (rule->fw_reject_code) { case IP_FW_REJECT_RST: { + /* XXX warning, this code writes into the mbuf */ struct tcphdr *const tcp = (struct tcphdr *) ((u_int32_t *)ip + ip->ip_hl); struct tcpiphdr ti, *const tip = (struct tcpiphdr *) ip; @@ -1412,7 +1419,7 @@ got_match: bcopy(&ti, ip, sizeof(ti)); NTOHL(tip->ti_seq); NTOHL(tip->ti_ack); - tip->ti_len = ip->ip_len - hlen - (tip->ti_off << 2); + tip->ti_len = ip_len - hlen - (tip->ti_off << 2); if (tcp->th_flags & TH_ACK) { tcp_respond(NULL, (void *)ip, tcp, *m, (tcp_seq)0, ntohl(tcp->th_ack), TH_RST); @@ -1443,6 +1450,7 @@ dropit: *m = NULL; } return(0); +#undef BRIDGED } /* @@ -1549,9 +1557,7 @@ del_entry(struct ip_fw_head *chainptr, u_short number) while (fcp && fcp->rule->fw_number == number) { struct ip_fw_chain *next; -#if STATEFUL - remove_dyn_rule(fcp, 1 /* force_delete */); -#endif + remove_dyn_rule(fcp, 1 /* delete */); next = LIST_NEXT(fcp, chain); LIST_REMOVE(fcp, chain); #ifdef DUMMYNET @@ -1835,7 +1841,6 @@ ip_fw_ctl(struct sockopt *sopt) for (fcp = LIST_FIRST(&ip_fw_chain), size = 0; fcp; fcp = LIST_NEXT(fcp, chain)) size += sizeof *fcp->rule; -#if STATEFUL if (ipfw_dyn_v) { int i ; struct ipfw_dyn_rule *p ; @@ -1844,7 +1849,6 @@ ip_fw_ctl(struct sockopt *sopt) for ( p = ipfw_dyn_v[i] ; p != NULL ; p = p->next ) size += sizeof(*p) ; } -#endif buf = malloc(size, M_TEMP, M_WAITOK); if (buf == 0) { error = ENOBUFS; @@ -1860,7 +1864,6 @@ ip_fw_ctl(struct sockopt *sopt) ((struct ip_fw_ext *)fcp->rule)->dyn_type; bp++; } -#if STATEFUL if (ipfw_dyn_v) { int i ; struct ipfw_dyn_rule *p, *dst, *last = NULL ; @@ -1880,17 +1883,14 @@ ip_fw_ctl(struct sockopt *sopt) if (last != NULL) last->next = NULL ; } -#endif error = sooptcopyout(sopt, buf, size); FREE(buf, M_TEMP); break; case IP_FW_FLUSH: -#if STATEFUL - s = splnet(); - remove_dyn_rule(NULL, 1 /* force delete */); - splx(s); -#endif + s = splnet(); + remove_dyn_rule(NULL, 1 /* force delete */); + splx(s); for (fcp = ip_fw_chain.lh_first; fcp != 0 && fcp->rule->fw_number != IPFW_DEFAULT_RULE; fcp = ip_fw_chain.lh_first) { @@ -2039,9 +2039,7 @@ ipfw_modevent(module_t mod, int type, void *unused) s = splnet(); ip_fw_chk_ptr = old_chk_ptr; ip_fw_ctl_ptr = old_ctl_ptr; -#if STATEFUL remove_dyn_rule(NULL, 1 /* force delete */); -#endif while (LIST_FIRST(&ip_fw_chain) != NULL) { struct ip_fw_chain *fcp = LIST_FIRST(&ip_fw_chain); LIST_REMOVE(LIST_FIRST(&ip_fw_chain), chain); |