X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fflow.c;h=5d2f33ca6ce0c01fe3d271a5ba5d9c55100d230c;hb=c2d967a562aaa57b679c302a5041d5a941154143;hp=6129703a2025314d1c644ecd5598c2b59981d6ac;hpb=cc34bc8c8611868474253b8fbd9e79cd66c60c94;p=openvswitch diff --git a/lib/flow.c b/lib/flow.c index 6129703a..5d2f33ca 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -26,6 +26,7 @@ #include #include "byte-order.h" #include "coverage.h" +#include "csum.h" #include "dynamic-string.h" #include "hash.h" #include "ofpbuf.h" @@ -179,7 +180,7 @@ parse_ipv6(struct ofpbuf *packet, struct flow *flow) || (nexthdr == IPPROTO_DSTOPTS)) { /* These headers, while different, have the fields we care about * in the same location and with the same interpretation. */ - const struct ip6_ext *ext_hdr = (struct ip6_ext *)packet->data; + const struct ip6_ext *ext_hdr = packet->data; nexthdr = ext_hdr->ip6e_nxt; if (!ofpbuf_try_pull(packet, (ext_hdr->ip6e_len + 1) * 8)) { return EINVAL; @@ -189,13 +190,13 @@ parse_ipv6(struct ofpbuf *packet, struct flow *flow) * we care about are in the same location as the generic * option header--only the header length is calculated * differently. */ - const struct ip6_ext *ext_hdr = (struct ip6_ext *)packet->data; + const struct ip6_ext *ext_hdr = packet->data; nexthdr = ext_hdr->ip6e_nxt; if (!ofpbuf_try_pull(packet, (ext_hdr->ip6e_len + 2) * 4)) { return EINVAL; } } else if (nexthdr == IPPROTO_FRAGMENT) { - const struct ip6_frag *frag_hdr = (struct ip6_frag *)packet->data; + const struct ip6_frag *frag_hdr = packet->data; nexthdr = frag_hdr->ip6f_nxt; if (!ofpbuf_try_pull(packet, sizeof *frag_hdr)) { @@ -744,6 +745,7 @@ flow_wildcards_combine(struct flow_wildcards *dst, dst->vlan_tci_mask = src1->vlan_tci_mask & src2->vlan_tci_mask; dst->tp_src_mask = src1->tp_src_mask & src2->tp_src_mask; dst->tp_dst_mask = src1->tp_dst_mask & src2->tp_dst_mask; + dst->nw_frag_mask = src1->nw_frag_mask & src2->nw_frag_mask; eth_addr_bitand(src1->dl_src_mask, src2->dl_src_mask, dst->dl_src_mask); eth_addr_bitand(src1->dl_dst_mask, src2->dl_dst_mask, dst->dl_dst_mask); eth_addr_bitand(src1->arp_sha_mask, src2->arp_sha_mask, dst->arp_sha_mask); @@ -783,6 +785,7 @@ flow_wildcards_equal(const struct flow_wildcards *a, || !ipv6_addr_equals(&a->nd_target_mask, &b->nd_target_mask) || a->tp_src_mask != b->tp_src_mask || a->tp_dst_mask != b->tp_dst_mask + || a->nw_frag_mask != b->nw_frag_mask || !eth_addr_equals(a->dl_src_mask, b->dl_src_mask) || !eth_addr_equals(a->dl_dst_mask, b->dl_dst_mask) || !eth_addr_equals(a->arp_sha_mask, b->arp_sha_mask) @@ -860,7 +863,8 @@ flow_wildcards_has_extra(const struct flow_wildcards *a, || (a->vlan_tci_mask & b->vlan_tci_mask) != b->vlan_tci_mask || (a->metadata_mask & b->metadata_mask) != b->metadata_mask || (a->tp_src_mask & b->tp_src_mask) != b->tp_src_mask - || (a->tp_dst_mask & b->tp_dst_mask) != b->tp_dst_mask); + || (a->tp_dst_mask & b->tp_dst_mask) != b->tp_dst_mask + || (a->nw_frag_mask & b->nw_frag_mask) != b->nw_frag_mask); } /* Sets the wildcard mask for register 'idx' in 'wc' to 'mask'. @@ -1009,7 +1013,7 @@ flow_set_vlan_pcp(struct flow *flow, uint8_t pcp) * 'flow'. * * (This is useful only for testing, obviously, and the packet isn't really - * valid. It hasn't got any checksums filled in, for one, and lots of fields + * valid. It hasn't got some checksums filled in, for one, and lots of fields * are just zeroed.) */ void flow_compose(struct ofpbuf *b, const struct flow *flow) @@ -1062,11 +1066,14 @@ flow_compose(struct ofpbuf *b, const struct flow *flow) b->l4 = icmp = ofpbuf_put_zeros(b, sizeof *icmp); icmp->icmp_type = ntohs(flow->tp_src); icmp->icmp_code = ntohs(flow->tp_dst); + icmp->icmp_csum = csum(icmp, ICMP_HEADER_LEN); } } + ip = b->l3; ip->ip_tot_len = htons((uint8_t *) b->data + b->size - (uint8_t *) b->l3); + ip->ip_csum = csum(ip, sizeof *ip); } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) { /* XXX */ } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {