aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow_netlink.c
diff options
context:
space:
mode:
authorJarno Rajahalme <jrajahalme@nicira.com>2015-02-05 16:40:49 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-08 01:40:17 -0500
commit83d2b9ba1abca241df44a502b6da950a25856b5b (patch)
tree16b6618df6b9cdbbf955457352cb71acd8cca324 /net/openvswitch/flow_netlink.c
parent2150f984258e7909327cb90115c8ff41b4e9acb5 (diff)
net: openvswitch: Support masked set actions.
OVS userspace already probes the openvswitch kernel module for OVS_ACTION_ATTR_SET_MASKED support. This patch adds the kernel module implementation of masked set actions. The existing set action sets many fields at once. When only a subset of the IP header fields, for example, should be modified, all the IP fields need to be exact matched so that the other field values can be copied to the set action. A masked set action allows modification of an arbitrary subset of the supported header bits without requiring the rest to be matched. Masked set action is now supported for all writeable key types, except for the tunnel key. The set tunnel action is an exception as any input tunnel info is cleared before action processing starts, so there is no tunnel info to mask. The kernel module converts all (non-tunnel) set actions to masked set actions. This makes action processing more uniform, and results in less branching and duplicating the action processing code. When returning actions to userspace, the fully masked set actions are converted back to normal set actions. We use a kernel internal action code to be able to tell the userspace provided and converted masked set actions apart. Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch/flow_netlink.c')
-rw-r--r--net/openvswitch/flow_netlink.c161
1 files changed, 127 insertions, 34 deletions
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 8b9a612b39d1..993281e6278d 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1695,16 +1695,6 @@ static int validate_and_copy_sample(const struct nlattr *attr,
1695 return 0; 1695 return 0;
1696} 1696}
1697 1697
1698static int validate_tp_port(const struct sw_flow_key *flow_key,
1699 __be16 eth_type)
1700{
1701 if ((eth_type == htons(ETH_P_IP) || eth_type == htons(ETH_P_IPV6)) &&
1702 (flow_key->tp.src || flow_key->tp.dst))
1703 return 0;
1704
1705 return -EINVAL;
1706}
1707
1708void ovs_match_init(struct sw_flow_match *match, 1698void ovs_match_init(struct sw_flow_match *match,
1709 struct sw_flow_key *key, 1699 struct sw_flow_key *key,
1710 struct sw_flow_mask *mask) 1700 struct sw_flow_mask *mask)
@@ -1805,23 +1795,45 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
1805 return err; 1795 return err;
1806} 1796}
1807 1797
1798/* Return false if there are any non-masked bits set.
1799 * Mask follows data immediately, before any netlink padding.
1800 */
1801static bool validate_masked(u8 *data, int len)
1802{
1803 u8 *mask = data + len;
1804
1805 while (len--)
1806 if (*data++ & ~*mask++)
1807 return false;
1808
1809 return true;
1810}
1811
1808static int validate_set(const struct nlattr *a, 1812static int validate_set(const struct nlattr *a,
1809 const struct sw_flow_key *flow_key, 1813 const struct sw_flow_key *flow_key,
1810 struct sw_flow_actions **sfa, 1814 struct sw_flow_actions **sfa,
1811 bool *set_tun, __be16 eth_type, bool log) 1815 bool *skip_copy, __be16 eth_type, bool masked, bool log)
1812{ 1816{
1813 const struct nlattr *ovs_key = nla_data(a); 1817 const struct nlattr *ovs_key = nla_data(a);
1814 int key_type = nla_type(ovs_key); 1818 int key_type = nla_type(ovs_key);
1819 size_t key_len;
1815 1820
1816 /* There can be only one key in a action */ 1821 /* There can be only one key in a action */
1817 if (nla_total_size(nla_len(ovs_key)) != nla_len(a)) 1822 if (nla_total_size(nla_len(ovs_key)) != nla_len(a))
1818 return -EINVAL; 1823 return -EINVAL;
1819 1824
1825 key_len = nla_len(ovs_key);
1826 if (masked)
1827 key_len /= 2;
1828
1820 if (key_type > OVS_KEY_ATTR_MAX || 1829 if (key_type > OVS_KEY_ATTR_MAX ||
1821 (ovs_key_lens[key_type].len != nla_len(ovs_key) && 1830 (ovs_key_lens[key_type].len != key_len &&
1822 ovs_key_lens[key_type].len != OVS_ATTR_NESTED)) 1831 ovs_key_lens[key_type].len != OVS_ATTR_NESTED))
1823 return -EINVAL; 1832 return -EINVAL;
1824 1833
1834 if (masked && !validate_masked(nla_data(ovs_key), key_len))
1835 return -EINVAL;
1836
1825 switch (key_type) { 1837 switch (key_type) {
1826 const struct ovs_key_ipv4 *ipv4_key; 1838 const struct ovs_key_ipv4 *ipv4_key;
1827 const struct ovs_key_ipv6 *ipv6_key; 1839 const struct ovs_key_ipv6 *ipv6_key;
@@ -1836,7 +1848,10 @@ static int validate_set(const struct nlattr *a,
1836 if (eth_p_mpls(eth_type)) 1848 if (eth_p_mpls(eth_type))
1837 return -EINVAL; 1849 return -EINVAL;
1838 1850
1839 *set_tun = true; 1851 if (masked)
1852 return -EINVAL; /* Masked tunnel set not supported. */
1853
1854 *skip_copy = true;
1840 err = validate_and_copy_set_tun(a, sfa, log); 1855 err = validate_and_copy_set_tun(a, sfa, log);
1841 if (err) 1856 if (err)
1842 return err; 1857 return err;
@@ -1846,48 +1861,66 @@ static int validate_set(const struct nlattr *a,
1846 if (eth_type != htons(ETH_P_IP)) 1861 if (eth_type != htons(ETH_P_IP))
1847 return -EINVAL; 1862 return -EINVAL;
1848 1863
1849 if (!flow_key->ip.proto)
1850 return -EINVAL;
1851
1852 ipv4_key = nla_data(ovs_key); 1864 ipv4_key = nla_data(ovs_key);
1853 if (ipv4_key->ipv4_proto != flow_key->ip.proto)
1854 return -EINVAL;
1855 1865
1856 if (ipv4_key->ipv4_frag != flow_key->ip.frag) 1866 if (masked) {
1857 return -EINVAL; 1867 const struct ovs_key_ipv4 *mask = ipv4_key + 1;
1858 1868
1869 /* Non-writeable fields. */
1870 if (mask->ipv4_proto || mask->ipv4_frag)
1871 return -EINVAL;
1872 } else {
1873 if (ipv4_key->ipv4_proto != flow_key->ip.proto)
1874 return -EINVAL;
1875
1876 if (ipv4_key->ipv4_frag != flow_key->ip.frag)
1877 return -EINVAL;
1878 }
1859 break; 1879 break;
1860 1880
1861 case OVS_KEY_ATTR_IPV6: 1881 case OVS_KEY_ATTR_IPV6:
1862 if (eth_type != htons(ETH_P_IPV6)) 1882 if (eth_type != htons(ETH_P_IPV6))
1863 return -EINVAL; 1883 return -EINVAL;
1864 1884
1865 if (!flow_key->ip.proto)
1866 return -EINVAL;
1867
1868 ipv6_key = nla_data(ovs_key); 1885 ipv6_key = nla_data(ovs_key);
1869 if (ipv6_key->ipv6_proto != flow_key->ip.proto)
1870 return -EINVAL;
1871 1886
1872 if (ipv6_key->ipv6_frag != flow_key->ip.frag) 1887 if (masked) {
1873 return -EINVAL; 1888 const struct ovs_key_ipv6 *mask = ipv6_key + 1;
1889
1890 /* Non-writeable fields. */
1891 if (mask->ipv6_proto || mask->ipv6_frag)
1892 return -EINVAL;
1893
1894 /* Invalid bits in the flow label mask? */
1895 if (ntohl(mask->ipv6_label) & 0xFFF00000)
1896 return -EINVAL;
1897 } else {
1898 if (ipv6_key->ipv6_proto != flow_key->ip.proto)
1899 return -EINVAL;
1874 1900
1901 if (ipv6_key->ipv6_frag != flow_key->ip.frag)
1902 return -EINVAL;
1903 }
1875 if (ntohl(ipv6_key->ipv6_label) & 0xFFF00000) 1904 if (ntohl(ipv6_key->ipv6_label) & 0xFFF00000)
1876 return -EINVAL; 1905 return -EINVAL;
1877 1906
1878 break; 1907 break;
1879 1908
1880 case OVS_KEY_ATTR_TCP: 1909 case OVS_KEY_ATTR_TCP:
1881 if (flow_key->ip.proto != IPPROTO_TCP) 1910 if ((eth_type != htons(ETH_P_IP) &&
1911 eth_type != htons(ETH_P_IPV6)) ||
1912 flow_key->ip.proto != IPPROTO_TCP)
1882 return -EINVAL; 1913 return -EINVAL;
1883 1914
1884 return validate_tp_port(flow_key, eth_type); 1915 break;
1885 1916
1886 case OVS_KEY_ATTR_UDP: 1917 case OVS_KEY_ATTR_UDP:
1887 if (flow_key->ip.proto != IPPROTO_UDP) 1918 if ((eth_type != htons(ETH_P_IP) &&
1919 eth_type != htons(ETH_P_IPV6)) ||
1920 flow_key->ip.proto != IPPROTO_UDP)
1888 return -EINVAL; 1921 return -EINVAL;
1889 1922
1890 return validate_tp_port(flow_key, eth_type); 1923 break;
1891 1924
1892 case OVS_KEY_ATTR_MPLS: 1925 case OVS_KEY_ATTR_MPLS:
1893 if (!eth_p_mpls(eth_type)) 1926 if (!eth_p_mpls(eth_type))
@@ -1895,15 +1928,45 @@ static int validate_set(const struct nlattr *a,
1895 break; 1928 break;
1896 1929
1897 case OVS_KEY_ATTR_SCTP: 1930 case OVS_KEY_ATTR_SCTP:
1898 if (flow_key->ip.proto != IPPROTO_SCTP) 1931 if ((eth_type != htons(ETH_P_IP) &&
1932 eth_type != htons(ETH_P_IPV6)) ||
1933 flow_key->ip.proto != IPPROTO_SCTP)
1899 return -EINVAL; 1934 return -EINVAL;
1900 1935
1901 return validate_tp_port(flow_key, eth_type); 1936 break;
1902 1937
1903 default: 1938 default:
1904 return -EINVAL; 1939 return -EINVAL;
1905 } 1940 }
1906 1941
1942 /* Convert non-masked non-tunnel set actions to masked set actions. */
1943 if (!masked && key_type != OVS_KEY_ATTR_TUNNEL) {
1944 int start, len = key_len * 2;
1945 struct nlattr *at;
1946
1947 *skip_copy = true;
1948
1949 start = add_nested_action_start(sfa,
1950 OVS_ACTION_ATTR_SET_TO_MASKED,
1951 log);
1952 if (start < 0)
1953 return start;
1954
1955 at = __add_action(sfa, key_type, NULL, len, log);
1956 if (IS_ERR(at))
1957 return PTR_ERR(at);
1958
1959 memcpy(nla_data(at), nla_data(ovs_key), key_len); /* Key. */
1960 memset(nla_data(at) + key_len, 0xff, key_len); /* Mask. */
1961 /* Clear non-writeable bits from otherwise writeable fields. */
1962 if (key_type == OVS_KEY_ATTR_IPV6) {
1963 struct ovs_key_ipv6 *mask = nla_data(at) + key_len;
1964
1965 mask->ipv6_label &= htonl(0x000FFFFF);
1966 }
1967 add_nested_action_end(*sfa, start);
1968 }
1969
1907 return 0; 1970 return 0;
1908} 1971}
1909 1972
@@ -1965,6 +2028,7 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
1965 [OVS_ACTION_ATTR_PUSH_VLAN] = sizeof(struct ovs_action_push_vlan), 2028 [OVS_ACTION_ATTR_PUSH_VLAN] = sizeof(struct ovs_action_push_vlan),
1966 [OVS_ACTION_ATTR_POP_VLAN] = 0, 2029 [OVS_ACTION_ATTR_POP_VLAN] = 0,
1967 [OVS_ACTION_ATTR_SET] = (u32)-1, 2030 [OVS_ACTION_ATTR_SET] = (u32)-1,
2031 [OVS_ACTION_ATTR_SET_MASKED] = (u32)-1,
1968 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1, 2032 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1,
1969 [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash) 2033 [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash)
1970 }; 2034 };
@@ -2060,7 +2124,14 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
2060 2124
2061 case OVS_ACTION_ATTR_SET: 2125 case OVS_ACTION_ATTR_SET:
2062 err = validate_set(a, key, sfa, 2126 err = validate_set(a, key, sfa,
2063 &skip_copy, eth_type, log); 2127 &skip_copy, eth_type, false, log);
2128 if (err)
2129 return err;
2130 break;
2131
2132 case OVS_ACTION_ATTR_SET_MASKED:
2133 err = validate_set(a, key, sfa,
2134 &skip_copy, eth_type, true, log);
2064 if (err) 2135 if (err)
2065 return err; 2136 return err;
2066 break; 2137 break;
@@ -2090,6 +2161,7 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
2090 return 0; 2161 return 0;
2091} 2162}
2092 2163
2164/* 'key' must be the masked key. */
2093int ovs_nla_copy_actions(const struct nlattr *attr, 2165int ovs_nla_copy_actions(const struct nlattr *attr,
2094 const struct sw_flow_key *key, 2166 const struct sw_flow_key *key,
2095 struct sw_flow_actions **sfa, bool log) 2167 struct sw_flow_actions **sfa, bool log)
@@ -2177,6 +2249,21 @@ static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
2177 return 0; 2249 return 0;
2178} 2250}
2179 2251
2252static int masked_set_action_to_set_action_attr(const struct nlattr *a,
2253 struct sk_buff *skb)
2254{
2255 const struct nlattr *ovs_key = nla_data(a);
2256 size_t key_len = nla_len(ovs_key) / 2;
2257
2258 /* Revert the conversion we did from a non-masked set action to
2259 * masked set action.
2260 */
2261 if (nla_put(skb, OVS_ACTION_ATTR_SET, nla_len(a) - key_len, ovs_key))
2262 return -EMSGSIZE;
2263
2264 return 0;
2265}
2266
2180int ovs_nla_put_actions(const struct nlattr *attr, int len, struct sk_buff *skb) 2267int ovs_nla_put_actions(const struct nlattr *attr, int len, struct sk_buff *skb)
2181{ 2268{
2182 const struct nlattr *a; 2269 const struct nlattr *a;
@@ -2192,6 +2279,12 @@ int ovs_nla_put_actions(const struct nlattr *attr, int len, struct sk_buff *skb)
2192 return err; 2279 return err;
2193 break; 2280 break;
2194 2281
2282 case OVS_ACTION_ATTR_SET_TO_MASKED:
2283 err = masked_set_action_to_set_action_attr(a, skb);
2284 if (err)
2285 return err;
2286 break;
2287
2195 case OVS_ACTION_ATTR_SAMPLE: 2288 case OVS_ACTION_ATTR_SAMPLE:
2196 err = sample_action_to_attr(a, skb); 2289 err = sample_action_to_attr(a, skb);
2197 if (err) 2290 if (err)