diff options
author | Christian Poessinger <christian@poessinger.com> | 2020-12-23 14:24:55 +0100 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2020-12-23 14:24:55 +0100 |
commit | 440ce3011e8718c917933026e68047fcfb008031 (patch) | |
tree | 67d71ba2555c9e4b9d1895ebb04406d5af92e7a9 | |
parent | 131b6ac0dfa0700820b2fe56adea2cad189b10ad (diff) | |
parent | 6f5eeaa22c32ab6e2c629a613fc5107d7b357b9d (diff) | |
download | vyos-1x-440ce3011e8718c917933026e68047fcfb008031.tar.gz vyos-1x-440ce3011e8718c917933026e68047fcfb008031.zip |
Merge branch 'xdp' of github.com:c-po/vyos-1x into current
* 'xdp' of github.com:c-po/vyos-1x:
bond: T2666: enable XDP support
xml: include: accel: convert dos/unix line endings
xdp: T2666: move CLI node to "interfaces ethernet <eth> xdp"
xdp: T2666: require at least 2 TX queues
-rw-r--r-- | interface-definitions/include/accel-client-ip-pool-start-stop.xml.i | 36 | ||||
-rw-r--r-- | interface-definitions/include/accel-mtu-128-16384.xml.i | 18 | ||||
-rw-r--r-- | interface-definitions/include/interface-xdp.xml.i | 8 | ||||
-rw-r--r-- | interface-definitions/interfaces-bonding.xml.in | 1 | ||||
-rw-r--r-- | interface-definitions/interfaces-ethernet.xml.in | 7 | ||||
-rw-r--r-- | python/vyos/ifconfig/ethernet.py | 27 | ||||
-rw-r--r-- | python/vyos/ifconfig/interface.py | 54 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-ethernet.py | 8 |
8 files changed, 85 insertions, 74 deletions
diff --git a/interface-definitions/include/accel-client-ip-pool-start-stop.xml.i b/interface-definitions/include/accel-client-ip-pool-start-stop.xml.i index a92c315f1..b578f2b2c 100644 --- a/interface-definitions/include/accel-client-ip-pool-start-stop.xml.i +++ b/interface-definitions/include/accel-client-ip-pool-start-stop.xml.i @@ -1,18 +1,18 @@ -<!-- included start from accel-client-ip-pool-start-stop.xml.i -->
-<leafNode name="start">
- <properties>
- <help>First IP address in the pool</help>
- <constraint>
- <validator name="ipv4-address"/>
- </constraint>
- </properties>
-</leafNode>
-<leafNode name="stop">
- <properties>
- <help>Last IP address in the pool</help>
- <constraint>
- <validator name="ipv4-address"/>
- </constraint>
- </properties>
-</leafNode>
-<!-- included end -->
+<!-- included start from accel-client-ip-pool-start-stop.xml.i --> +<leafNode name="start"> + <properties> + <help>First IP address in the pool</help> + <constraint> + <validator name="ipv4-address"/> + </constraint> + </properties> +</leafNode> +<leafNode name="stop"> + <properties> + <help>Last IP address in the pool</help> + <constraint> + <validator name="ipv4-address"/> + </constraint> + </properties> +</leafNode> +<!-- included end --> diff --git a/interface-definitions/include/accel-mtu-128-16384.xml.i b/interface-definitions/include/accel-mtu-128-16384.xml.i index 72ab550f9..7ee483056 100644 --- a/interface-definitions/include/accel-mtu-128-16384.xml.i +++ b/interface-definitions/include/accel-mtu-128-16384.xml.i @@ -1,9 +1,9 @@ - <leafNode name="mtu">
- <properties>
- <help>Maximum Transmission Unit (MTU) - default 1492</help>
- <constraint>
- <validator name="numeric" argument="--range 128-16384"/>
- </constraint>
- </properties>
- <defaultValue>1492</defaultValue>
- </leafNode>
+ <leafNode name="mtu"> + <properties> + <help>Maximum Transmission Unit (MTU) - default 1492</help> + <constraint> + <validator name="numeric" argument="--range 128-16384"/> + </constraint> + </properties> + <defaultValue>1492</defaultValue> + </leafNode> diff --git a/interface-definitions/include/interface-xdp.xml.i b/interface-definitions/include/interface-xdp.xml.i new file mode 100644 index 000000000..d224c177f --- /dev/null +++ b/interface-definitions/include/interface-xdp.xml.i @@ -0,0 +1,8 @@ +<!-- included start from interface-vrf.xml.i --> +<leafNode name="xdp"> + <properties> + <help>Enable eXpress Data Path</help> + <valueless/> + </properties> +</leafNode> +<!-- included end --> diff --git a/interface-definitions/interfaces-bonding.xml.in b/interface-definitions/interfaces-bonding.xml.in index 423d94f76..720daba4d 100644 --- a/interface-definitions/interfaces-bonding.xml.in +++ b/interface-definitions/interfaces-bonding.xml.in @@ -165,6 +165,7 @@ </leafNode> #include <include/vif-s.xml.i> #include <include/vif.xml.i> + #include <include/interface-xdp.xml.i> </children> </tagNode> </children> diff --git a/interface-definitions/interfaces-ethernet.xml.in b/interface-definitions/interfaces-ethernet.xml.in index d3d94cf8d..5dd685c37 100644 --- a/interface-definitions/interfaces-ethernet.xml.in +++ b/interface-definitions/interfaces-ethernet.xml.in @@ -95,12 +95,6 @@ <valueless/> </properties> </leafNode> - <leafNode name="xdp"> - <properties> - <help>Enable eXpress Data Path</help> - <valueless/> - </properties> - </leafNode> </children> </node> <leafNode name="speed"> @@ -193,6 +187,7 @@ </node> #include <include/vif-s.xml.i> #include <include/vif.xml.i> + #include <include/interface-xdp.xml.i> </children> </tagNode> </children> diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index 5c8c42461..1bec45879 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -270,30 +270,6 @@ class EthernetIf(Interface): raise ValueError("Value out of range") return self.set_interface('ufo', 'on' if state else 'off') - def set_xdp(self, state): - """ - Enable Kernel XDP support. State can be either True or False. - - Example: - >>> from vyos.ifconfig import EthernetIf - >>> i = EthernetIf('eth0') - >>> i.set_xdp(True) - """ - if not isinstance(state, bool): - raise ValueError("Value out of range") - - ifname = self.config['ifname'] - cmd = f'xdp_loader -d {ifname} -U --auto-mode' - if state: - # Using 'xdp' will automatically decide if the driver supports - # 'xdpdrv' or only 'xdpgeneric'. A user later sees which driver is - # actually in use by calling 'ip a' or 'show interfaces ethernet' - cmd = f'xdp_loader -d {ifname} --auto-mode -F --progsec xdp_router ' \ - f'--filename /usr/share/vyos/xdp/xdp_prog_kern.o && ' \ - f'xdp_prog_user -d {ifname}' - - return self._cmd(cmd) - def set_ring_buffer(self, b_type, b_size): """ Example: @@ -340,9 +316,6 @@ class EthernetIf(Interface): # UDP fragmentation offloading self.set_ufo(dict_search('offload.ufo', config) != None) - # eXpress Data Path - highly experimental - self.set_xdp(dict_search('offload.xdp', config) != None) - # Set physical interface speed and duplex if {'speed', 'duplex'} <= set(config): speed = config.get('speed') diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 7026223b1..e5c51134b 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -733,7 +733,6 @@ class Interface(Control): >>> Interface('eth0').set_proxy_arp_pvlan(1) """ self.set_interface('proxy_arp_pvlan', enable) - def get_addr(self): """ @@ -889,7 +888,7 @@ class Interface(Control): # drop all interface addresses first self.flush_addrs() - + ifname = self.ifname for bridge, bridge_config in bridge_dict.items(): @@ -903,18 +902,18 @@ class Interface(Control): # set bridge port path priority if 'priority' in bridge_config: self.set_path_cost(bridge_config['priority']) - + vlan_filter = 0 vlan_add = set() - + del_ifname_vlan_ids = get_vlan_ids(ifname) bridge_vlan_filter = Section.klass(bridge)(bridge, create=True).get_vlan_filter() - + if bridge_vlan_filter: if 1 in del_ifname_vlan_ids: del_ifname_vlan_ids.remove(1) vlan_filter = 1 - + for vlan in del_ifname_vlan_ids: cmd = f'bridge vlan del dev {ifname} vid {vlan}' self._cmd(cmd) @@ -937,13 +936,13 @@ class Interface(Control): cmd = f'bridge vlan add dev {self.ifname} vid {vlan} master' self._cmd(cmd) vlan_add.add(vlan) - + if vlan_filter: # Setting VLAN ID for the bridge for vlan in vlan_add: cmd = f'bridge vlan add dev {bridge} vid {vlan} self' self._cmd(cmd) - + # enable/disable Vlan Filter # When the VLAN aware option is not detected, the setting of `bridge` should not be overwritten Section.klass(bridge)(bridge, create=True).set_vlan_filter(vlan_filter) @@ -1041,7 +1040,7 @@ class Interface(Control): # Remove existing mirroring rules self.del_tc_qdisc(ifname,'ingress','ffff:') self.del_tc_qdisc(ifname,'prio','1:') - + # Setting up packet mirroring ingress_mirror = dict_search('mirror.ingress', self._config) # if interface does yet not exist bail out early and @@ -1053,7 +1052,7 @@ class Interface(Control): # Export the mirrored traffic to the interface mirror_cmd = f'tc filter add dev {ifname} parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress mirror dev {ingress_mirror}' self._cmd(mirror_cmd) - + egress_mirror = dict_search('mirror.egress', self._config) # if interface does yet not exist bail out early and # add it later @@ -1071,14 +1070,14 @@ class Interface(Control): # https://man7.org/linux/man-pages/man8/tc-mirred.8.html ifname = self._config['ifname'] mirror_rules = self._config.get('is_monitor_intf') - + # Remove existing mirroring rules # The rule must be completely deleted first for rule in mirror_rules: for intf, dire in rule.items(): self.del_tc_qdisc(intf,'ingress','ffff:') self.del_tc_qdisc(intf,'prio','1:') - + # Setting mirror rules for rule in mirror_rules: for intf, dire in rule.items(): @@ -1098,6 +1097,30 @@ class Interface(Control): mirror_cmd = f'tc filter add dev {intf} parent 1: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress mirror dev {ifname}' self._cmd(mirror_cmd) + def set_xdp(self, state): + """ + Enable Kernel XDP support. State can be either True or False. + + Example: + >>> from vyos.ifconfig import Interface + >>> i = Interface('eth0') + >>> i.set_xdp(True) + """ + if not isinstance(state, bool): + raise ValueError("Value out of range") + + ifname = self.config['ifname'] + cmd = f'xdp_loader -d {ifname} -U --auto-mode' + if state: + # Using 'xdp' will automatically decide if the driver supports + # 'xdpdrv' or only 'xdpgeneric'. A user later sees which driver is + # actually in use by calling 'ip a' or 'show interfaces ethernet' + cmd = f'xdp_loader -d {ifname} --auto-mode -F --progsec xdp_router ' \ + f'--filename /usr/share/vyos/xdp/xdp_prog_kern.o && ' \ + f'xdp_prog_user -d {ifname}' + + return self._cmd(cmd) + def update(self, config): """ General helper function which works on a dictionary retrived by get_config_dict(). It's main intention is to consolidate the scattered @@ -1265,11 +1288,14 @@ class Interface(Control): if 'is_bridge_member' in config: bridge_dict = config.get('is_bridge_member') self.add_to_bridge(bridge_dict) - + # Re-set rules for the mirror monitoring interface if 'is_monitor_intf' in config: self.apply_mirror_of_monitor() - + + # eXpress Data Path - highly experimental + self.set_xdp('xdp' in config) + # remove no longer required 802.1ad (Q-in-Q VLANs) ifname = config['ifname'] for vif_s_id in config.get('vif_s_remove', {}): diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 1f622c003..b358e9725 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -16,6 +16,7 @@ import os +from glob import glob from sys import exit from vyos.config import Config @@ -28,6 +29,7 @@ from vyos.configverify import verify_mtu_ipv6 from vyos.configverify import verify_vlan_config from vyos.configverify import verify_vrf from vyos.ifconfig import EthernetIf +from vyos.util import dict_search from vyos import ConfigError from vyos import airbag airbag.enable() @@ -66,6 +68,12 @@ def verify(ethernet): verify_address(ethernet) verify_vrf(ethernet) + # XDP requires multiple TX queues + if 'xdp' in ethernet: + queues = glob('/sys/class/net/{ifname}/queues/tx-*'.format(**ethernet)) + if len(queues) < 2: + raise ConfigError('XDP requires additional TX queues, too few available!') + if {'is_bond_member', 'mac'} <= set(ethernet): print(f'WARNING: changing mac address "{mac}" will be ignored as "{ifname}" ' f'is a member of bond "{is_bond_member}"'.format(**ethernet)) |