datapath.c (74f84a5726c7d08c27745305e67474b8645c541d) datapath.c (7d5437c709ded4f152cb8b305d17972d6707f20c)
1/*
2 * Copyright (c) 2007-2012 Nicira, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but

--- 348 unchanged lines hidden (view full) ---

357 consume_skb(skb);
358 } while ((skb = nskb));
359 return err;
360}
361
362static size_t key_attr_size(void)
363{
364 return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
1/*
2 * Copyright (c) 2007-2012 Nicira, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but

--- 348 unchanged lines hidden (view full) ---

357 consume_skb(skb);
358 } while ((skb = nskb));
359 return err;
360}
361
362static size_t key_attr_size(void)
363{
364 return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
365 + nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */
366 + nla_total_size(8) /* OVS_TUNNEL_KEY_ATTR_ID */
367 + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_SRC */
368 + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_DST */
369 + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TOS */
370 + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TTL */
371 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
372 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */
365 + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */
366 + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */
367 + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
368 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
369 + nla_total_size(4) /* OVS_KEY_ATTR_8021Q */
370 + nla_total_size(0) /* OVS_KEY_ATTR_ENCAP */
371 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
372 + nla_total_size(40) /* OVS_KEY_ATTR_IPV6 */

--- 222 unchanged lines hidden (view full) ---

595 } else if (flow_key->eth.type == htons(ETH_P_IPV6)) {
596 if (flow_key->ipv6.tp.src || flow_key->ipv6.tp.dst)
597 return 0;
598 }
599
600 return -EINVAL;
601}
602
373 + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */
374 + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */
375 + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
376 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
377 + nla_total_size(4) /* OVS_KEY_ATTR_8021Q */
378 + nla_total_size(0) /* OVS_KEY_ATTR_ENCAP */
379 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
380 + nla_total_size(40) /* OVS_KEY_ATTR_IPV6 */

--- 222 unchanged lines hidden (view full) ---

603 } else if (flow_key->eth.type == htons(ETH_P_IPV6)) {
604 if (flow_key->ipv6.tp.src || flow_key->ipv6.tp.dst)
605 return 0;
606 }
607
608 return -EINVAL;
609}
610
611static int validate_and_copy_set_tun(const struct nlattr *attr,
612 struct sw_flow_actions **sfa)
613{
614 struct ovs_key_ipv4_tunnel tun_key;
615 int err, start;
616
617 err = ovs_ipv4_tun_from_nlattr(nla_data(attr), &tun_key);
618 if (err)
619 return err;
620
621 start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET);
622 if (start < 0)
623 return start;
624
625 err = add_action(sfa, OVS_KEY_ATTR_IPV4_TUNNEL, &tun_key, sizeof(tun_key));
626 add_nested_action_end(*sfa, start);
627
628 return err;
629}
630
603static int validate_set(const struct nlattr *a,
631static int validate_set(const struct nlattr *a,
604 const struct sw_flow_key *flow_key)
632 const struct sw_flow_key *flow_key,
633 struct sw_flow_actions **sfa,
634 bool *set_tun)
605{
606 const struct nlattr *ovs_key = nla_data(a);
607 int key_type = nla_type(ovs_key);
608
609 /* There can be only one key in a action */
610 if (nla_total_size(nla_len(ovs_key)) != nla_len(a))
611 return -EINVAL;
612
613 if (key_type > OVS_KEY_ATTR_MAX ||
635{
636 const struct nlattr *ovs_key = nla_data(a);
637 int key_type = nla_type(ovs_key);
638
639 /* There can be only one key in a action */
640 if (nla_total_size(nla_len(ovs_key)) != nla_len(a))
641 return -EINVAL;
642
643 if (key_type > OVS_KEY_ATTR_MAX ||
614 nla_len(ovs_key) != ovs_key_lens[key_type])
644 (ovs_key_lens[key_type] != nla_len(ovs_key) &&
645 ovs_key_lens[key_type] != -1))
615 return -EINVAL;
616
617 switch (key_type) {
618 const struct ovs_key_ipv4 *ipv4_key;
619 const struct ovs_key_ipv6 *ipv6_key;
646 return -EINVAL;
647
648 switch (key_type) {
649 const struct ovs_key_ipv4 *ipv4_key;
650 const struct ovs_key_ipv6 *ipv6_key;
651 int err;
620
621 case OVS_KEY_ATTR_PRIORITY:
622 case OVS_KEY_ATTR_SKB_MARK:
623 case OVS_KEY_ATTR_ETHERNET:
624 break;
625
652
653 case OVS_KEY_ATTR_PRIORITY:
654 case OVS_KEY_ATTR_SKB_MARK:
655 case OVS_KEY_ATTR_ETHERNET:
656 break;
657
658 case OVS_KEY_ATTR_TUNNEL:
659 *set_tun = true;
660 err = validate_and_copy_set_tun(a, sfa);
661 if (err)
662 return err;
663 break;
664
626 case OVS_KEY_ATTR_IPV4:
627 if (flow_key->eth.type != htons(ETH_P_IP))
628 return -EINVAL;
629
630 if (!flow_key->ip.proto)
631 return -EINVAL;
632
633 ipv4_key = nla_data(ovs_key);

--- 132 unchanged lines hidden (view full) ---

766 vlan = nla_data(a);
767 if (vlan->vlan_tpid != htons(ETH_P_8021Q))
768 return -EINVAL;
769 if (!(vlan->vlan_tci & htons(VLAN_TAG_PRESENT)))
770 return -EINVAL;
771 break;
772
773 case OVS_ACTION_ATTR_SET:
665 case OVS_KEY_ATTR_IPV4:
666 if (flow_key->eth.type != htons(ETH_P_IP))
667 return -EINVAL;
668
669 if (!flow_key->ip.proto)
670 return -EINVAL;
671
672 ipv4_key = nla_data(ovs_key);

--- 132 unchanged lines hidden (view full) ---

805 vlan = nla_data(a);
806 if (vlan->vlan_tpid != htons(ETH_P_8021Q))
807 return -EINVAL;
808 if (!(vlan->vlan_tci & htons(VLAN_TAG_PRESENT)))
809 return -EINVAL;
810 break;
811
812 case OVS_ACTION_ATTR_SET:
774 err = validate_set(a, key);
813 err = validate_set(a, key, sfa, &skip_copy);
775 if (err)
776 return err;
777 break;
778
779 case OVS_ACTION_ATTR_SAMPLE:
780 err = validate_and_copy_sample(a, key, depth, sfa);
781 if (err)
782 return err;

--- 205 unchanged lines hidden (view full) ---

988 break;
989 }
990 }
991
992 nla_nest_end(skb, start);
993 return err;
994}
995
814 if (err)
815 return err;
816 break;
817
818 case OVS_ACTION_ATTR_SAMPLE:
819 err = validate_and_copy_sample(a, key, depth, sfa);
820 if (err)
821 return err;

--- 205 unchanged lines hidden (view full) ---

1027 break;
1028 }
1029 }
1030
1031 nla_nest_end(skb, start);
1032 return err;
1033}
1034
1035static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
1036{
1037 const struct nlattr *ovs_key = nla_data(a);
1038 int key_type = nla_type(ovs_key);
1039 struct nlattr *start;
1040 int err;
1041
1042 switch (key_type) {
1043 case OVS_KEY_ATTR_IPV4_TUNNEL:
1044 start = nla_nest_start(skb, OVS_ACTION_ATTR_SET);
1045 if (!start)
1046 return -EMSGSIZE;
1047
1048 err = ovs_ipv4_tun_to_nlattr(skb, nla_data(ovs_key));
1049 if (err)
1050 return err;
1051 nla_nest_end(skb, start);
1052 break;
1053 default:
1054 if (nla_put(skb, OVS_ACTION_ATTR_SET, nla_len(a), ovs_key))
1055 return -EMSGSIZE;
1056 break;
1057 }
1058
1059 return 0;
1060}
1061
996static int actions_to_attr(const struct nlattr *attr, int len, struct sk_buff *skb)
997{
998 const struct nlattr *a;
999 int rem, err;
1000
1001 nla_for_each_attr(a, attr, len, rem) {
1002 int type = nla_type(a);
1003
1004 switch (type) {
1062static int actions_to_attr(const struct nlattr *attr, int len, struct sk_buff *skb)
1063{
1064 const struct nlattr *a;
1065 int rem, err;
1066
1067 nla_for_each_attr(a, attr, len, rem) {
1068 int type = nla_type(a);
1069
1070 switch (type) {
1071 case OVS_ACTION_ATTR_SET:
1072 err = set_action_to_attr(a, skb);
1073 if (err)
1074 return err;
1075 break;
1076
1005 case OVS_ACTION_ATTR_SAMPLE:
1006 err = sample_action_to_attr(a, skb);
1007 if (err)
1008 return err;
1009 break;
1010 default:
1011 if (nla_put(skb, type, nla_len(a), nla_data(a)))
1012 return -EMSGSIZE;

--- 1307 unchanged lines hidden ---
1077 case OVS_ACTION_ATTR_SAMPLE:
1078 err = sample_action_to_attr(a, skb);
1079 if (err)
1080 return err;
1081 break;
1082 default:
1083 if (nla_put(skb, type, nla_len(a), nla_data(a)))
1084 return -EMSGSIZE;

--- 1307 unchanged lines hidden ---