aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r--net/openvswitch/flow.c54
1 files changed, 45 insertions, 9 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 4010423f2831..913bdc1a83c0 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -462,6 +462,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
462 * update skb->csum here. 462 * update skb->csum here.
463 */ 463 */
464 464
465 key->eth.tci = 0;
465 if (vlan_tx_tag_present(skb)) 466 if (vlan_tx_tag_present(skb))
466 key->eth.tci = htons(skb->vlan_tci); 467 key->eth.tci = htons(skb->vlan_tci);
467 else if (eth->h_proto == htons(ETH_P_8021Q)) 468 else if (eth->h_proto == htons(ETH_P_8021Q))
@@ -482,6 +483,8 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
482 483
483 error = check_iphdr(skb); 484 error = check_iphdr(skb);
484 if (unlikely(error)) { 485 if (unlikely(error)) {
486 memset(&key->ip, 0, sizeof(key->ip));
487 memset(&key->ipv4, 0, sizeof(key->ipv4));
485 if (error == -EINVAL) { 488 if (error == -EINVAL) {
486 skb->transport_header = skb->network_header; 489 skb->transport_header = skb->network_header;
487 error = 0; 490 error = 0;
@@ -503,8 +506,10 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
503 return 0; 506 return 0;
504 } 507 }
505 if (nh->frag_off & htons(IP_MF) || 508 if (nh->frag_off & htons(IP_MF) ||
506 skb_shinfo(skb)->gso_type & SKB_GSO_UDP) 509 skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
507 key->ip.frag = OVS_FRAG_TYPE_FIRST; 510 key->ip.frag = OVS_FRAG_TYPE_FIRST;
511 else
512 key->ip.frag = OVS_FRAG_TYPE_NONE;
508 513
509 /* Transport layer. */ 514 /* Transport layer. */
510 if (key->ip.proto == IPPROTO_TCP) { 515 if (key->ip.proto == IPPROTO_TCP) {
@@ -513,18 +518,25 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
513 key->tp.src = tcp->source; 518 key->tp.src = tcp->source;
514 key->tp.dst = tcp->dest; 519 key->tp.dst = tcp->dest;
515 key->tp.flags = TCP_FLAGS_BE16(tcp); 520 key->tp.flags = TCP_FLAGS_BE16(tcp);
521 } else {
522 memset(&key->tp, 0, sizeof(key->tp));
516 } 523 }
524
517 } else if (key->ip.proto == IPPROTO_UDP) { 525 } else if (key->ip.proto == IPPROTO_UDP) {
518 if (udphdr_ok(skb)) { 526 if (udphdr_ok(skb)) {
519 struct udphdr *udp = udp_hdr(skb); 527 struct udphdr *udp = udp_hdr(skb);
520 key->tp.src = udp->source; 528 key->tp.src = udp->source;
521 key->tp.dst = udp->dest; 529 key->tp.dst = udp->dest;
530 } else {
531 memset(&key->tp, 0, sizeof(key->tp));
522 } 532 }
523 } else if (key->ip.proto == IPPROTO_SCTP) { 533 } else if (key->ip.proto == IPPROTO_SCTP) {
524 if (sctphdr_ok(skb)) { 534 if (sctphdr_ok(skb)) {
525 struct sctphdr *sctp = sctp_hdr(skb); 535 struct sctphdr *sctp = sctp_hdr(skb);
526 key->tp.src = sctp->source; 536 key->tp.src = sctp->source;
527 key->tp.dst = sctp->dest; 537 key->tp.dst = sctp->dest;
538 } else {
539 memset(&key->tp, 0, sizeof(key->tp));
528 } 540 }
529 } else if (key->ip.proto == IPPROTO_ICMP) { 541 } else if (key->ip.proto == IPPROTO_ICMP) {
530 if (icmphdr_ok(skb)) { 542 if (icmphdr_ok(skb)) {
@@ -534,33 +546,44 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
534 * them in 16-bit network byte order. */ 546 * them in 16-bit network byte order. */
535 key->tp.src = htons(icmp->type); 547 key->tp.src = htons(icmp->type);
536 key->tp.dst = htons(icmp->code); 548 key->tp.dst = htons(icmp->code);
549 } else {
550 memset(&key->tp, 0, sizeof(key->tp));
537 } 551 }
538 } 552 }
539 553
540 } else if ((key->eth.type == htons(ETH_P_ARP) || 554 } else if (key->eth.type == htons(ETH_P_ARP) ||
541 key->eth.type == htons(ETH_P_RARP)) && arphdr_ok(skb)) { 555 key->eth.type == htons(ETH_P_RARP)) {
542 struct arp_eth_header *arp; 556 struct arp_eth_header *arp;
543 557
544 arp = (struct arp_eth_header *)skb_network_header(skb); 558 arp = (struct arp_eth_header *)skb_network_header(skb);
545 559
546 if (arp->ar_hrd == htons(ARPHRD_ETHER) 560 if (arphdr_ok(skb) &&
547 && arp->ar_pro == htons(ETH_P_IP) 561 arp->ar_hrd == htons(ARPHRD_ETHER) &&
548 && arp->ar_hln == ETH_ALEN 562 arp->ar_pro == htons(ETH_P_IP) &&
549 && arp->ar_pln == 4) { 563 arp->ar_hln == ETH_ALEN &&
564 arp->ar_pln == 4) {
550 565
551 /* We only match on the lower 8 bits of the opcode. */ 566 /* We only match on the lower 8 bits of the opcode. */
552 if (ntohs(arp->ar_op) <= 0xff) 567 if (ntohs(arp->ar_op) <= 0xff)
553 key->ip.proto = ntohs(arp->ar_op); 568 key->ip.proto = ntohs(arp->ar_op);
569 else
570 key->ip.proto = 0;
571
554 memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); 572 memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src));
555 memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); 573 memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst));
556 ether_addr_copy(key->ipv4.arp.sha, arp->ar_sha); 574 ether_addr_copy(key->ipv4.arp.sha, arp->ar_sha);
557 ether_addr_copy(key->ipv4.arp.tha, arp->ar_tha); 575 ether_addr_copy(key->ipv4.arp.tha, arp->ar_tha);
576 } else {
577 memset(&key->ip, 0, sizeof(key->ip));
578 memset(&key->ipv4, 0, sizeof(key->ipv4));
558 } 579 }
559 } else if (key->eth.type == htons(ETH_P_IPV6)) { 580 } else if (key->eth.type == htons(ETH_P_IPV6)) {
560 int nh_len; /* IPv6 Header + Extensions */ 581 int nh_len; /* IPv6 Header + Extensions */
561 582
562 nh_len = parse_ipv6hdr(skb, key); 583 nh_len = parse_ipv6hdr(skb, key);
563 if (unlikely(nh_len < 0)) { 584 if (unlikely(nh_len < 0)) {
585 memset(&key->ip, 0, sizeof(key->ip));
586 memset(&key->ipv6.addr, 0, sizeof(key->ipv6.addr));
564 if (nh_len == -EINVAL) { 587 if (nh_len == -EINVAL) {
565 skb->transport_header = skb->network_header; 588 skb->transport_header = skb->network_header;
566 error = 0; 589 error = 0;
@@ -582,24 +605,32 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
582 key->tp.src = tcp->source; 605 key->tp.src = tcp->source;
583 key->tp.dst = tcp->dest; 606 key->tp.dst = tcp->dest;
584 key->tp.flags = TCP_FLAGS_BE16(tcp); 607 key->tp.flags = TCP_FLAGS_BE16(tcp);
608 } else {
609 memset(&key->tp, 0, sizeof(key->tp));
585 } 610 }
586 } else if (key->ip.proto == NEXTHDR_UDP) { 611 } else if (key->ip.proto == NEXTHDR_UDP) {
587 if (udphdr_ok(skb)) { 612 if (udphdr_ok(skb)) {
588 struct udphdr *udp = udp_hdr(skb); 613 struct udphdr *udp = udp_hdr(skb);
589 key->tp.src = udp->source; 614 key->tp.src = udp->source;
590 key->tp.dst = udp->dest; 615 key->tp.dst = udp->dest;
616 } else {
617 memset(&key->tp, 0, sizeof(key->tp));
591 } 618 }
592 } else if (key->ip.proto == NEXTHDR_SCTP) { 619 } else if (key->ip.proto == NEXTHDR_SCTP) {
593 if (sctphdr_ok(skb)) { 620 if (sctphdr_ok(skb)) {
594 struct sctphdr *sctp = sctp_hdr(skb); 621 struct sctphdr *sctp = sctp_hdr(skb);
595 key->tp.src = sctp->source; 622 key->tp.src = sctp->source;
596 key->tp.dst = sctp->dest; 623 key->tp.dst = sctp->dest;
624 } else {
625 memset(&key->tp, 0, sizeof(key->tp));
597 } 626 }
598 } else if (key->ip.proto == NEXTHDR_ICMP) { 627 } else if (key->ip.proto == NEXTHDR_ICMP) {
599 if (icmp6hdr_ok(skb)) { 628 if (icmp6hdr_ok(skb)) {
600 error = parse_icmpv6(skb, key, nh_len); 629 error = parse_icmpv6(skb, key, nh_len);
601 if (error) 630 if (error)
602 return error; 631 return error;
632 } else {
633 memset(&key->tp, 0, sizeof(key->tp));
603 } 634 }
604 } 635 }
605 } 636 }
@@ -615,13 +646,19 @@ int ovs_flow_key_extract(struct ovs_key_ipv4_tunnel *tun_key,
615 struct sk_buff *skb, struct sw_flow_key *key) 646 struct sk_buff *skb, struct sw_flow_key *key)
616{ 647{
617 /* Extract metadata from packet. */ 648 /* Extract metadata from packet. */
618 memset(key, 0, sizeof(*key));
619 if (tun_key) 649 if (tun_key)
620 memcpy(&key->tun_key, tun_key, sizeof(key->tun_key)); 650 memcpy(&key->tun_key, tun_key, sizeof(key->tun_key));
651 else
652 memset(&key->tun_key, 0, sizeof(key->tun_key));
621 653
622 key->phy.priority = skb->priority; 654 key->phy.priority = skb->priority;
623 key->phy.in_port = OVS_CB(skb)->input_vport->port_no; 655 key->phy.in_port = OVS_CB(skb)->input_vport->port_no;
624 key->phy.skb_mark = skb->mark; 656 key->phy.skb_mark = skb->mark;
657 key->ovs_flow_hash = 0;
658 key->recirc_id = 0;
659
660 /* Flags are always used as part of stats */
661 key->tp.flags = 0;
625 662
626 return key_extract(skb, key); 663 return key_extract(skb, key);
627} 664}
@@ -632,7 +669,6 @@ int ovs_flow_key_extract_userspace(const struct nlattr *attr,
632{ 669{
633 int err; 670 int err;
634 671
635 memset(key, 0, sizeof(*key));
636 /* Extract metadata from netlink attributes. */ 672 /* Extract metadata from netlink attributes. */
637 err = ovs_nla_get_flow_metadata(attr, key); 673 err = ovs_nla_get_flow_metadata(attr, key);
638 if (err) 674 if (err)