summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_mroute.c
diff options
context:
space:
mode:
authorhsu <hsu@FreeBSD.org>2003-08-19 17:22:51 +0000
committerhsu <hsu@FreeBSD.org>2003-08-19 17:22:51 +0000
commit54fc4fe4303630d4130d47ce6a29c9978797adf4 (patch)
tree5b519cfcc7c716f1a82f9698a8eccee5c2856efd /sys/netinet/ip_mroute.c
parente7c75a19b0066c1b685f60e768f03166937a8c37 (diff)
downloadFreeBSD-src-54fc4fe4303630d4130d47ce6a29c9978797adf4.zip
FreeBSD-src-54fc4fe4303630d4130d47ce6a29c9978797adf4.tar.gz
* Bug fix in bw_meter_process(): the periodically processed bins
of bw_meter entries were processed up to one second ahead. After an unappropriate rescheduling of some of the bw_meter entries, the upcalls weren't delivered. * pim_register_prepare() uses the appropriate sw_csum flag to call ip_fragment() so the IP checksum is computed properly. * Modify pim_register_prepare() to take care of IP packets that don't need fragmentation. * Add-back in_delayed_cksum() to encap_send(), because it seems it should be there. Submitted by: Pavlin Radoslavov <pavlin@icir.org>
Diffstat (limited to 'sys/netinet/ip_mroute.c')
-rw-r--r--sys/netinet/ip_mroute.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 50ffdca..dfc1910 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -1734,6 +1734,12 @@ encap_send(struct ip *ip, struct vif *vifp, struct mbuf *m)
struct ip *ip_copy;
int i, len = ip->ip_len;
+ /* Take care of delayed checksums */
+ if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ in_delayed_cksum(m);
+ m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+ }
+
/*
* copy the old packet & pullup its IP header into the
* new mbuf so we can modify it. Try to fill the new
@@ -2696,15 +2702,17 @@ bw_meter_process()
* processed to the current one. On entry, i points to the last bucket
* visited, so we need to increment i at the beginning of the loop.
*/
- for (i = (now.tv_sec - loops + 1) % BW_METER_BUCKETS; loops > 0; loops--) {
+ for (i = (now.tv_sec - loops) % BW_METER_BUCKETS; loops > 0; loops--) {
struct bw_meter *x, *tmp_list;
if (++i >= BW_METER_BUCKETS)
i = 0;
+ /* Disconnect the list of bw_meter entries from the bin */
tmp_list = bw_meter_timers[i];
bw_meter_timers[i] = NULL;
+ /* Process the list of bw_meter entries */
while (tmp_list != NULL) {
x = tmp_list;
tmp_list = tmp_list->bm_time_next;
@@ -2717,9 +2725,18 @@ bw_meter_process()
int time_hash;
BW_METER_TIMEHASH(x, time_hash);
+ if (time_hash == i && process_endtime.tv_sec == now.tv_sec) {
+ /*
+ * XXX: somehow the bin processing is a bit ahead of time.
+ * Put the entry in the next bin.
+ */
+ if (++time_hash >= BW_METER_BUCKETS)
+ time_hash = 0;
+ }
x->bm_time_next = bw_meter_timers[time_hash];
bw_meter_timers[time_hash] = x;
x->bm_time_hash = time_hash;
+
continue;
}
@@ -2825,16 +2842,12 @@ pim_register_prepare(struct ip *ip, struct mbuf *m)
struct mbuf *mb_copy = NULL;
int mtu;
- /*
- * XXX: take care of delayed checksums.
- * XXX: if network interfaces are capable of computing checksum for
- * encapsulated multicast data packets, we need to reconsider this.
- */
+ /* Take care of delayed checksums */
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
-
+
/*
* Copy the old packet & pullup its IP header into the
* new mbuf so we can modify it.
@@ -2852,9 +2865,19 @@ pim_register_prepare(struct ip *ip, struct mbuf *m)
/* Compute the MTU after the PIM Register encapsulation */
mtu = 0xffff - sizeof(pim_encap_iphdr) - sizeof(pim_encap_pimhdr);
- if (ip_fragment(ip, &mb_copy, mtu, 0, 0) != 0) {
- m_freem(mb_copy);
- return NULL;
+
+ if (ip->ip_len <= mtu) {
+ /* Turn the IP header into a valid one */
+ ip->ip_len = htons(ip->ip_len);
+ ip->ip_off = htons(ip->ip_off);
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(mb_copy, ip->ip_hl << 2);
+ } else {
+ /* Fragment the packet */
+ if (ip_fragment(ip, &mb_copy, mtu, 0, CSUM_DELAY_IP) != 0) {
+ m_freem(mb_copy);
+ return NULL;
+ }
}
return mb_copy;
}
OpenPOWER on IntegriCloud