diff options
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | interface-definitions/interfaces-ethernet.xml | 856 | ||||
| -rw-r--r-- | python/vyos/ifconfig.py | 13 | ||||
| -rwxr-xr-x | src/conf_mode/interface-ethernet.py | 298 | 
4 files changed, 1170 insertions, 3 deletions
| @@ -11,8 +11,12 @@ interface_definitions:  	# XXX: delete top level node.def's that now live in other packages  	rm -f $(TMPL_DIR)/firewall/node.def  	rm -f $(TMPL_DIR)/interfaces/node.def -	rm -f $(TMPL_DIR)/interfaces/bridge/node.tag/ip/node.def  	rm -f $(TMPL_DIR)/interfaces/bonding/node.tag/ip/node.def +	rm -f $(TMPL_DIR)/interfaces/bridge/node.tag/ip/node.def +	rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/ip/node.def +	rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/vif/node.tag/ip/node.def +	rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/vif-s/node.tag/ip/node.def +	rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/vif-s/node.tag/vif-c/node.tag/ip/node.def  	rm -f $(TMPL_DIR)/interfaces/vxlan/node.tag/ip/node.def  	rm -f $(TMPL_DIR)/protocols/node.def  	rm -f $(TMPL_DIR)/protocols/static/node.def diff --git a/interface-definitions/interfaces-ethernet.xml b/interface-definitions/interfaces-ethernet.xml new file mode 100644 index 000000000..a2de4aeb3 --- /dev/null +++ b/interface-definitions/interfaces-ethernet.xml @@ -0,0 +1,856 @@ +<?xml version="1.0"?> +<interfaceDefinition> +  <node name="interfaces"> +    <children> +      <tagNode name="ethernet" owner="${vyos_conf_scripts_dir}/interface-ethernet.py"> +        <properties> +          <help>Ethernet interface name</help> +          <priority>318</priority> +          <constraint> +            <regex>((eth|lan)[0-9]+|(eno|ens|enp|enx).+)$</regex> +          </constraint> +          <constraintErrorMessage>Invalid Ethernet interface name</constraintErrorMessage> +          <valueHelp> +            <format>ethN</format> +            <description>Ethernet interface name</description> +          </valueHelp> +          <valueHelp> +            <format>en[ospx]N</format> +            <description>Ethernet interface name</description> +          </valueHelp> +        </properties> +        <children> +          <leafNode name="address"> +            <properties> +              <help>IP address</help> +              <completionHelp> +                <list>dhcp dhcpv6</list> +              </completionHelp> +              <valueHelp> +                <format>ipv4net</format> +                <description>IPv4 address and prefix length</description> +              </valueHelp> +              <valueHelp> +                <format>ipv6net</format> +                <description>IPv6 address and prefix length</description> +              </valueHelp> +              <valueHelp> +                <format>dhcp</format> +                <description>Dynamic Host Configuration Protocol</description> +              </valueHelp> +              <valueHelp> +                <format>dhcpv6</format> +                <description>Dynamic Host Configuration Protocol for IPv6</description> +              </valueHelp> +              <constraint> +                <validator name="ip-cidr"/> +                <regex>(dhcp|dhcpv6)</regex> +              </constraint> +              <multi/> +            </properties> +          </leafNode> +          <leafNode name="description"> +            <properties> +              <help>Interface description</help> +              <constraint> +                <regex>^.{1,256}$</regex> +              </constraint> +              <constraintErrorMessage>Interface description too long (limit 256 characters)</constraintErrorMessage> +            </properties> +          </leafNode> +          <node name="dhcp-options"> +            <properties> +              <help>DHCP options</help> +            </properties> +            <children> +              <leafNode name="client-id"> +                <properties> +                  <help>DHCP client identifier</help> +                </properties> +              </leafNode> +              <leafNode name="host-name"> +                <properties> +                  <help>DHCP client host name (overrides the system host name)</help> +                </properties> +              </leafNode> +            </children> +          </node> +          <node name="dhcpv6-options"> +            <properties> +              <help>DHCPv6 options</help> +              <priority>319</priority> +            </properties> +            <children> +              <leafNode name="parameters-only"> +                <properties> +                  <help>Acquire only config parameters, no address</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="temporary"> +                <properties> +                  <help>IPv6 "temporary" address</help> +                  <valueless/> +                </properties> +              </leafNode> +            </children> +          </node> +          <leafNode name="disable-flow-control"> +            <properties> +              <help>Disable Ethernet flow control (pause frames)</help> +              <valueless/> +            </properties> +          </leafNode> +          <leafNode name="disable-link-detect"> +            <properties> +              <help>Ignore link state changes</help> +              <valueless/> +            </properties> +          </leafNode> +          <leafNode name="disable"> +            <properties> +              <help>Disable this bridge interface</help> +              <valueless/> +            </properties> +          </leafNode> +          <leafNode name="duplex"> +            <properties> +              <help>Duplex mode</help> +              <completionHelp> +                <list>auto half full</list> +              </completionHelp> +              <valueHelp> +                <format>auto</format> +                <description>Auto negotiation (default)</description> +              </valueHelp> +              <valueHelp> +                <format>half</format> +                <description>Half duplex</description> +              </valueHelp> +              <valueHelp> +                <format>full</format> +                <description>Full duplex</description> +              </valueHelp> +              <constraint> +                <regex>(auto|half|full)</regex> +              </constraint> +              <constraintErrorMessage>duplex must be auto, half or full</constraintErrorMessage> +            </properties> +          </leafNode> +          <leafNode name="hw-id"> +            <properties> +              <help>Media Access Control (MAC) address</help> +              <valueHelp> +                <format>h:h:h:h:h:h</format> +                <description>Hardware (MAC) address</description> +              </valueHelp> +              <constraint> +                <validator name="mac-address"/> +              </constraint> +            </properties> +          </leafNode> +          <node name="ip"> +            <children> +              <leafNode name="arp-cache-timeout"> +                <properties> +                  <help>ARP cache entry timeout in seconds</help> +                  <valueHelp> +                    <format>1-86400</format> +                    <description>ARP cache entry timout in seconds (default 30)</description> +                  </valueHelp> +                  <constraint> +                    <validator name="numeric" argument="--range 1-86400"/> +                  </constraint> +                  <constraintErrorMessage>ARP cache entry timeout must be between 1 and 86400 seconds</constraintErrorMessage> +                </properties> +              </leafNode> +              <leafNode name="enable-proxy-arp"> +                <properties> +                  <help>Enable proxy-arp on this interface</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="proxy-arp-pvlan"> +                <properties> +                  <help>Enable private VLAN proxy ARP on this interface</help> +                  <valueless/> +                </properties> +              </leafNode> +            </children> +          </node> +          <leafNode name="mac"> +            <properties> +              <help>Media Access Control (MAC) address</help> +              <valueHelp> +                <format>h:h:h:h:h:h</format> +                <description>Hardware (MAC) address</description> +              </valueHelp> +              <constraint> +                <validator name="mac-address"/> +              </constraint> +            </properties> +          </leafNode> +          <leafNode name="mtu"> +            <properties> +              <help>Maximum Transmission Unit (MTU)</help> +              <valueHelp> +                <format>68-9000</format> +                <description>Maximum Transmission Unit</description> +              </valueHelp> +              <constraint> +                <validator name="numeric" argument="--range 68-9000"/> +              </constraint> +              <constraintErrorMessage>MTU must be between 68 and 9000</constraintErrorMessage> +            </properties> +          </leafNode> +          <node name="offload-options"> +            <properties> +              <help>Configurable offload options</help> +            </properties> +            <children> +              <leafNode name="generic-receive"> +                <properties> +                  <help>Configure GRO (generic receive offload)</help> +                  <completionHelp> +                    <list>on off</list> +                  </completionHelp> +                  <valueHelp> +                    <format>on</format> +                    <description>Enable GRO (generic receive offload)</description> +                  </valueHelp> +                  <valueHelp> +                    <format>off</format> +                    <description>Disable GRO (generic receive offload)</description> +                  </valueHelp> +                  <constraint> +                    <regex>(on|off)</regex> +                  </constraint> +                  <constraintErrorMessage>Must be either 'on' or 'off'</constraintErrorMessage> +                </properties> +              </leafNode> +              <leafNode name="generic-segmentation"> +                <properties> +                  <help>Configure GSO (generic segmentation offload)</help> +                  <completionHelp> +                    <list>on off</list> +                  </completionHelp> +                  <valueHelp> +                    <format>on</format> +                    <description>Enable GSO (generic segmentation offload)</description> +                  </valueHelp> +                  <valueHelp> +                    <format>off</format> +                    <description>Disable GSO (generic segmentation offload)</description> +                  </valueHelp> +                  <constraint> +                    <regex>(on|off)</regex> +                  </constraint> +                  <constraintErrorMessage>Must be either 'on' or 'off'</constraintErrorMessage> +                </properties> +              </leafNode> +              <leafNode name="scatter-gather"> +                <properties> +                  <help>Configure scatter-gather option</help> +                  <completionHelp> +                    <list>on off</list> +                  </completionHelp> +                  <valueHelp> +                    <format>on</format> +                    <description>Enable scatter-gather</description> +                  </valueHelp> +                  <valueHelp> +                    <format>off</format> +                    <description>Disable scatter-gather</description> +                  </valueHelp> +                  <constraint> +                    <regex>(on|off)</regex> +                  </constraint> +                  <constraintErrorMessage>Must be either 'on' or 'off'</constraintErrorMessage> +                </properties> +              </leafNode> +              <leafNode name="tcp-segmentation"> +                <properties> +                  <help>Configure TSO (TCP segmentation offloading)</help> +                  <completionHelp> +                    <list>on off</list> +                  </completionHelp> +                  <valueHelp> +                    <format>on</format> +                    <description>Enable TSO (TCP segmentation offloading)</description> +                  </valueHelp> +                  <valueHelp> +                    <format>off</format> +                    <description>Disable TSO (TCP segmentation offloading)</description> +                  </valueHelp> +                  <constraint> +                    <regex>(on|off)</regex> +                  </constraint> +                  <constraintErrorMessage>Must be either 'on' or 'off'</constraintErrorMessage> +                </properties> +              </leafNode> +              <leafNode name="udp-fragmentation"> +                <properties> +                  <help>Configure UDP fragmentation offloading</help> +                  <completionHelp> +                    <list>on off</list> +                  </completionHelp> +                  <valueHelp> +                    <format>on</format> +                    <description>Enable UDP fragmentation offloading</description> +                  </valueHelp> +                  <valueHelp> +                    <format>off</format> +                    <description>Disable UDP fragmentation offloading</description> +                  </valueHelp> +                  <constraint> +                    <regex>(on|off)</regex> +                  </constraint> +                  <constraintErrorMessage>Must be either 'on' or 'off'</constraintErrorMessage> +                </properties> +              </leafNode> +            </children> +          </node> +          <leafNode name="smp-affinity"> +            <properties> +              <help>CPU interrupt affinity mask</help> +              <completionHelp> +                <list>auto 10 100 1000 2500 5000 10000</list> +              </completionHelp> +              <valueHelp> +                <format>auto</format> +                <description>Auto negotiation (default)</description> +              </valueHelp> +              <valueHelp> +                <format>hex</format> +                <description>Bitmask representing CPUs that this NIC will interrupt</description> +              </valueHelp> +              <valueHelp> +                <format>hex,hex</format> +                <description>Bitmasks representing CPUs for interrupt and receive processing</description> +              </valueHelp> +              <constraint> +                <regex>(auto)</regex> +                <regex>[0-9a-f]+(|,[0-9a-f]+)$</regex> +              </constraint> +              <constraintErrorMessage>IRQ affinity mask must be hex value or auto</constraintErrorMessage> +            </properties> +          </leafNode> +          <leafNode name="speed"> +            <properties> +              <help>Link speed</help> +              <completionHelp> +                <list>auto 10 100 1000 2500 5000 10000</list> +              </completionHelp> +              <valueHelp> +                <format>auto</format> +                <description>Auto negotiation (default)</description> +              </valueHelp> +              <valueHelp> +                <format>10</format> +                <description>10 Mbit/sec</description> +              </valueHelp> +              <valueHelp> +                <format>100</format> +                <description>100 Mbit/sec</description> +              </valueHelp> +              <valueHelp> +                <format>1000</format> +                <description>1 Gbit/sec</description> +              </valueHelp> +              <valueHelp> +                <format>2500</format> +                <description>2.5 Gbit/sec</description> +              </valueHelp> +              <valueHelp> +                <format>5000</format> +                <description>5 Gbit/sec</description> +              </valueHelp> +              <valueHelp> +                <format>10000</format> +                <description>10 Gbit/sec</description> +              </valueHelp> +              <constraint> +                <regex>(auto|10|100|1000|2500|5000|10000)</regex> +              </constraint> +              <constraintErrorMessage>Speed must be auto, 10, 100, 1000, 2500, 5000 or 10000</constraintErrorMessage> +            </properties> +          </leafNode> +          <tagNode name="vif-s"> +            <properties> +              <help>QinQ TAG-S Virtual Local Area Network (VLAN) ID</help> +              <constraint> +                <validator name="numeric" argument="--range 0-4094"/> +              </constraint> +              <constraintErrorMessage>VLAN ID must be between 0 and 4094</constraintErrorMessage> +            </properties> +            <children> +              <leafNode name="address"> +                <properties> +                  <help>IP address</help> +                  <completionHelp> +                    <list>dhcp dhcpv6</list> +                  </completionHelp> +                  <valueHelp> +                    <format>ipv4net</format> +                    <description>IPv4 address and prefix length</description> +                  </valueHelp> +                  <valueHelp> +                    <format>ipv6net</format> +                    <description>IPv6 address and prefix length</description> +                  </valueHelp> +                  <valueHelp> +                    <format>dhcp</format> +                    <description>Dynamic Host Configuration Protocol</description> +                  </valueHelp> +                  <valueHelp> +                    <format>dhcpv6</format> +                    <description>Dynamic Host Configuration Protocol for IPv6</description> +                  </valueHelp> +                  <constraint> +                    <validator name="ip-cidr"/> +                    <regex>(dhcp|dhcpv6)</regex> +                  </constraint> +                  <multi/> +                </properties> +              </leafNode> +              <leafNode name="description"> +                <properties> +                  <help>Interface description</help> +                  <constraint> +                    <regex>^.{1,256}$</regex> +                  </constraint> +                  <constraintErrorMessage>Interface description too long (limit 256 characters)</constraintErrorMessage> +                </properties> +              </leafNode> +              <node name="dhcp-options"> +                <properties> +                  <help>DHCP options</help> +                </properties> +                <children> +                  <leafNode name="client-id"> +                    <properties> +                      <help>DHCP client identifier</help> +                    </properties> +                  </leafNode> +                  <leafNode name="host-name"> +                    <properties> +                      <help>DHCP client host name (overrides the system host name)</help> +                    </properties> +                  </leafNode> +                </children> +              </node> +              <node name="dhcpv6-options"> +                <properties> +                  <help>DHCPv6 options</help> +                  <priority>319</priority> +                </properties> +                <children> +                  <leafNode name="parameters-only"> +                    <properties> +                      <help>Acquire only config parameters, no address</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="temporary"> +                    <properties> +                      <help>IPv6 "temporary" address</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                </children> +              </node> +              <leafNode name="disable-link-detect"> +                <properties> +                  <help>Ignore link state changes</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="disable"> +                <properties> +                  <help>Disable this bridge interface</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="ethertype"> +                <properties> +                  <help>Set Ethertype</help> +                  <completionHelp> +                    <list>0x88A8 0x8100</list> +                  </completionHelp> +                  <valueHelp> +                    <format>0x88A8</format> +                    <description>802.1ad</description> +                  </valueHelp> +                  <valueHelp> +                    <format>0x8100</format> +                    <description>802.1q</description> +                  </valueHelp> +                  <constraint> +                    <regex>(0x88A8|0x8100)</regex> +                  </constraint> +                  <constraintErrorMessage>Ethertype must be 0x88A8 or 0x8100</constraintErrorMessage> +                </properties> +              </leafNode> +              <node name="ip"> +                <children> +                  <leafNode name="enable-proxy-arp"> +                    <properties> +                      <help>Enable proxy-arp on this interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="proxy-arp-pvlan"> +                    <properties> +                      <help>Enable private VLAN proxy ARP on this interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                </children> +              </node> +              <leafNode name="mac"> +                <properties> +                  <help>Media Access Control (MAC) address</help> +                  <valueHelp> +                    <format>h:h:h:h:h:h</format> +                    <description>Hardware (MAC) address</description> +                  </valueHelp> +                  <constraint> +                    <validator name="mac-address"/> +                  </constraint> +                </properties> +              </leafNode> +              <leafNode name="mtu"> +                <properties> +                  <help>Maximum Transmission Unit (MTU)</help> +                  <valueHelp> +                    <format>68-9000</format> +                    <description>Maximum Transmission Unit</description> +                  </valueHelp> +                  <constraint> +                    <validator name="numeric" argument="--range 68-9000"/> +                  </constraint> +                  <constraintErrorMessage>MTU must be between 68 and 9000</constraintErrorMessage> +                </properties> +              </leafNode> +              <tagNode name="vif-c"> +                <properties> +                  <help>QinQ TAG-C Virtual Local Area Network (VLAN) ID</help> +                  <constraint> +                    <validator name="numeric" argument="--range 0-4094"/> +                  </constraint> +                  <constraintErrorMessage>VLAN ID must be between 0 and 4094</constraintErrorMessage> +                </properties> +                <children> +                  <leafNode name="address"> +                    <properties> +                      <help>IP address</help> +                      <completionHelp> +                        <list>dhcp dhcpv6</list> +                      </completionHelp> +                      <valueHelp> +                        <format>ipv4net</format> +                        <description>IPv4 address and prefix length</description> +                      </valueHelp> +                      <valueHelp> +                        <format>ipv6net</format> +                        <description>IPv6 address and prefix length</description> +                      </valueHelp> +                      <valueHelp> +                        <format>dhcp</format> +                        <description>Dynamic Host Configuration Protocol</description> +                      </valueHelp> +                      <valueHelp> +                        <format>dhcpv6</format> +                        <description>Dynamic Host Configuration Protocol for IPv6</description> +                      </valueHelp> +                      <constraint> +                        <validator name="ip-cidr"/> +                        <regex>(dhcp|dhcpv6)</regex> +                      </constraint> +                      <multi/> +                    </properties> +                  </leafNode> +                  <leafNode name="description"> +                    <properties> +                      <help>Interface description</help> +                      <constraint> +                        <regex>^.{1,256}$</regex> +                      </constraint> +                      <constraintErrorMessage>Interface description too long (limit 256 characters)</constraintErrorMessage> +                    </properties> +                  </leafNode> +                  <node name="dhcp-options"> +                    <properties> +                      <help>DHCP options</help> +                    </properties> +                    <children> +                      <leafNode name="client-id"> +                        <properties> +                          <help>DHCP client identifier</help> +                        </properties> +                      </leafNode> +                      <leafNode name="host-name"> +                        <properties> +                          <help>DHCP client host name (overrides the system host name)</help> +                        </properties> +                      </leafNode> +                    </children> +                  </node> +                  <node name="dhcpv6-options"> +                    <properties> +                      <help>DHCPv6 options</help> +                      <priority>319</priority> +                    </properties> +                    <children> +                      <leafNode name="parameters-only"> +                        <properties> +                          <help>Acquire only config parameters, no address</help> +                          <valueless/> +                        </properties> +                      </leafNode> +                      <leafNode name="temporary"> +                        <properties> +                          <help>IPv6 "temporary" address</help> +                          <valueless/> +                        </properties> +                      </leafNode> +                    </children> +                  </node> +                  <leafNode name="disable-link-detect"> +                    <properties> +                      <help>Ignore link state changes</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="disable"> +                    <properties> +                      <help>Disable this bridge interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <node name="ip"> +                    <children> +                      <leafNode name="enable-proxy-arp"> +                        <properties> +                          <help>Enable proxy-arp on this interface</help> +                          <valueless/> +                        </properties> +                      </leafNode> +                      <leafNode name="proxy-arp-pvlan"> +                        <properties> +                          <help>Enable private VLAN proxy ARP on this interface</help> +                          <valueless/> +                        </properties> +                      </leafNode> +                    </children> +                  </node> +                  <leafNode name="mac"> +                    <properties> +                      <help>Media Access Control (MAC) address</help> +                      <valueHelp> +                        <format>h:h:h:h:h:h</format> +                        <description>Hardware (MAC) address</description> +                      </valueHelp> +                      <constraint> +                        <validator name="mac-address"/> +                      </constraint> +                    </properties> +                  </leafNode> +                  <leafNode name="mtu"> +                    <properties> +                      <help>Maximum Transmission Unit (MTU)</help> +                      <valueHelp> +                        <format>68-9000</format> +                        <description>Maximum Transmission Unit</description> +                      </valueHelp> +                      <constraint> +                        <validator name="numeric" argument="--range 68-9000"/> +                      </constraint> +                      <constraintErrorMessage>MTU must be between 68 and 9000</constraintErrorMessage> +                    </properties> +                  </leafNode> +                </children> +              </tagNode> +            </children> +          </tagNode> +          <tagNode name="vif"> +            <properties> +              <help>Virtual Local Area Network (VLAN) ID</help> +              <constraint> +                <validator name="numeric" argument="--range 0-4094"/> +              </constraint> +              <constraintErrorMessage>VLAN ID must be between 0 and 4094</constraintErrorMessage> +            </properties> +            <children> +              <leafNode name="address"> +                <properties> +                  <help>IP address</help> +                  <completionHelp> +                    <list>dhcp dhcpv6</list> +                  </completionHelp> +                  <valueHelp> +                    <format>ipv4net</format> +                    <description>IPv4 address and prefix length</description> +                  </valueHelp> +                  <valueHelp> +                    <format>ipv6net</format> +                    <description>IPv6 address and prefix length</description> +                  </valueHelp> +                  <valueHelp> +                    <format>dhcp</format> +                    <description>Dynamic Host Configuration Protocol</description> +                  </valueHelp> +                  <valueHelp> +                    <format>dhcpv6</format> +                    <description>Dynamic Host Configuration Protocol for IPv6</description> +                  </valueHelp> +                  <constraint> +                    <validator name="ip-cidr"/> +                    <regex>(dhcp|dhcpv6)</regex> +                  </constraint> +                  <multi/> +                </properties> +              </leafNode> +              <leafNode name="description"> +                <properties> +                  <help>Interface description</help> +                  <constraint> +                    <regex>^.{1,256}$</regex> +                  </constraint> +                  <constraintErrorMessage>Interface description too long (limit 256 characters)</constraintErrorMessage> +                </properties> +              </leafNode> +              <node name="dhcp-options"> +                <properties> +                  <help>DHCP options</help> +                </properties> +                <children> +                  <leafNode name="client-id"> +                    <properties> +                      <help>DHCP client identifier</help> +                    </properties> +                  </leafNode> +                  <leafNode name="host-name"> +                    <properties> +                      <help>DHCP client host name (overrides the system host name)</help> +                    </properties> +                  </leafNode> +                </children> +              </node> +              <node name="dhcpv6-options"> +                <properties> +                  <help>DHCPv6 options</help> +                  <priority>319</priority> +                </properties> +                <children> +                  <leafNode name="parameters-only"> +                    <properties> +                      <help>Acquire only config parameters, no address</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="temporary"> +                    <properties> +                      <help>IPv6 "temporary" address</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                </children> +              </node> +              <leafNode name="disable-link-detect"> +                <properties> +                  <help>Ignore link state changes</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="disable"> +                <properties> +                  <help>Disable this bridge interface</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="egress-qos"> +                <properties> +                  <help>VLAN egress QoS</help> +                  <completionHelp> +                    <script>echo Format for qos mapping \"0:1 1:6 7:6\"</script> +                  </completionHelp> +                  <constraint> +                    <regex>[:0-7 ]+$</regex> +                  </constraint> +                  <constraintErrorMessage>QoS mapping should be in the format of \"0:7 2:3\" with numbers 0-9</constraintErrorMessage> +                </properties> +              </leafNode> +              <leafNode name="ingress-qos"> +                <properties> +                  <help>VLAN ingress QoS</help> +                  <completionHelp> +                    <script>echo Format for qos mapping \"0:1 1:6 7:6\"</script> +                  </completionHelp> +                  <constraint> +                    <regex>[:0-7 ]+$</regex> +                  </constraint> +                  <constraintErrorMessage>QoS mapping should be in the format of \"0:7 2:3\" with numbers 0-9</constraintErrorMessage> +                </properties> +              </leafNode> +              <node name="ip"> +                <children> +                  <leafNode name="arp-cache-timeout"> +                    <properties> +                      <help>ARP cache entry timeout in seconds</help> +                      <valueHelp> +                        <format>1-86400</format> +                        <description>ARP cache entry timout in seconds (default 30)</description> +                      </valueHelp> +                      <constraint> +                        <validator name="numeric" argument="--range 1-86400"/> +                      </constraint> +                      <constraintErrorMessage>ARP cache entry timeout must be between 1 and 86400 seconds</constraintErrorMessage> +                    </properties> +                  </leafNode> +                  <leafNode name="enable-proxy-arp"> +                    <properties> +                      <help>Enable proxy-arp on this interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="proxy-arp-pvlan"> +                    <properties> +                      <help>Enable private VLAN proxy ARP on this interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                </children> +              </node> +              <leafNode name="mac"> +                <properties> +                  <help>Media Access Control (MAC) address</help> +                  <valueHelp> +                    <format>h:h:h:h:h:h</format> +                    <description>Hardware (MAC) address</description> +                  </valueHelp> +                  <constraint> +                    <validator name="mac-address"/> +                  </constraint> +                </properties> +              </leafNode> +              <leafNode name="mtu"> +                <properties> +                  <help>Maximum Transmission Unit (MTU)</help> +                  <valueHelp> +                    <format>68-9000</format> +                    <description>Maximum Transmission Unit</description> +                  </valueHelp> +                  <constraint> +                    <validator name="numeric" argument="--range 68-9000"/> +                  </constraint> +                  <constraintErrorMessage>MTU must be between 68 and 9000</constraintErrorMessage> +                </properties> +              </leafNode> +            </children> +          </tagNode> +        </children> +      </tagNode> +    </children> +  </node> +</interfaceDefinition> diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py index 524c0f276..7181ff42f 100644 --- a/python/vyos/ifconfig.py +++ b/python/vyos/ifconfig.py @@ -1047,8 +1047,18 @@ class VLANIf(Interface):          tmp.remove() -class BondIf(VLANIf): +class EthernetIf(VLANIf): +    """ +    Abstraction of a Linux Ethernet Interface +    """ +    def __init__(self, ifname): +        super().__init__(ifname) +    def remove(self): +        raise OSError('Ethernet interfaces can not be removed') + + +class BondIf(VLANIf):      """      The Linux bonding driver provides a method for aggregating multiple network      interfaces into a single logical "bonded" interface. The behavior of the @@ -1056,7 +1066,6 @@ class BondIf(VLANIf):      either hot standby or load balancing services. Additionally, link integrity      monitoring may be performed.      """ -      def __init__(self, ifname):          super().__init__(ifname, type='bond') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py new file mode 100755 index 000000000..4aed13a62 --- /dev/null +++ b/src/conf_mode/interface-ethernet.py @@ -0,0 +1,298 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. + +import os + +from copy import deepcopy +from sys import exit + +from vyos.ifconfig import EthernetIf, VLANIf +from vyos.configdict import list_diff, vlan_to_dict +from vyos.config import Config +from vyos import ConfigError + +default_config_data = { +    'address': [], +    'address_remove': [], +    'description': '', +    'deleted': False, +    'dhcp_client_id': '', +    'dhcp_hostname': '', +    'dhcpv6_prm_only': False, +    'dhcpv6_temporary': False, +    'disable': False, +    'disable_link_detect': 1, +    'hw_id': '', +    'ip_arp_cache_tmo': 30, +    'ip_proxy_arp': 0, +    'ip_proxy_arp_pvlan': 0, +    'intf': '', +    'mac': '', +    'mtu': 1500, +    'vif_s': [], +    'vif_s_remove': [], +    'vif': [], +    'vif_remove': [] +} + + +def apply_vlan_config(vlan, config): +    """ +    Generic function to apply a VLAN configuration from a dictionary +    to a VLAN interface +    """ + +    if type(vlan) != type(VLANIf("lo")): +        raise TypeError() + +    # update interface description used e.g. within SNMP +    vlan.ifalias = config['description'] +    # ignore link state changes +    vlan.link_detect = config['disable_link_detect'] +    # Maximum Transmission Unit (MTU) +    vlan.mtu = config['mtu'] +    # Change VLAN interface MAC address +    if config['mac']: +        vlan.mac = config['mac'] + +    # enable/disable VLAN interface +    if config['disable']: +        vlan.state = 'down' +    else: +        vlan.state = 'up' + +    # Configure interface address(es) +    # - not longer required addresses get removed first +    # - newly addresses will be added second +    for addr in config['address_remove']: +        vlan.del_addr(addr) +    for addr in config['address']: +        vlan.add_addr(addr) + + +def get_config(): +    eth = deepcopy(default_config_data) +    conf = Config() + +    # determine tagNode instance +    try: +        eth['intf'] = os.environ['VYOS_TAGNODE_VALUE'] +    except KeyError as E: +        print("Interface not specified") + +    # check if ethernet interface has been removed +    cfg_base = 'interfaces ethernet ' + eth['intf'] +    if not conf.exists(cfg_base): +        eth['deleted'] = True +        # we can not bail out early as ethernet interface can not be removed +        # Kernel will complain with: RTNETLINK answers: Operation not supported. +        # Thus we need to remove individual settings +        return eth + +    # set new configuration level +    conf.set_level(cfg_base) + +    # retrieve configured interface addresses +    if conf.exists('address'): +        eth['address'] = conf.return_values('address') + +    # get interface addresses (currently effective) - to determine which +    # address is no longer valid and needs to be removed +    eff_addr = conf.return_effective_values('address') +    eth['address_remove'] = list_diff(eff_addr, eth['address']) + +    # retrieve interface description +    if conf.exists('description'): +        eth['description'] = conf.return_value('description') +    else: +        eth['description'] = eth['intf'] + +    # get DHCP client identifier +    if conf.exists('dhcp-options client-id'): +        eth['dhcp_client_id'] = conf.return_value('dhcp-options client-id') + +    # DHCP client host name (overrides the system host name) +    if conf.exists('dhcp-options host-name'): +        eth['dhcp_hostname'] = conf.return_value('dhcp-options host-name') + +    # DHCPv6 only acquire config parameters, no address +    if conf.exists('dhcpv6-options parameters-only'): +        eth['dhcpv6_prm_only'] = conf.return_value('dhcpv6-options parameters-only') + +    # DHCPv6 temporary IPv6 address +    if conf.exists('dhcpv6-options temporary'): +        eth['dhcpv6_temporary'] = conf.return_value('dhcpv6-options temporary') + +    # ignore link state changes +    if conf.exists('disable-link-detect'): +        eth['disable_link_detect'] = 2 + +    # disable interface +    if conf.exists('disable'): +        eth['disable'] = True + +    # ARP cache entry timeout in seconds +    if conf.exists('ip arp-cache-timeout'): +        eth['ip_arp_cache_tmo'] = int(conf.return_value('ip arp-cache-timeout')) + +    # Enable proxy-arp on this interface +    if conf.exists('ip enable-proxy-arp'): +        eth['ip_proxy_arp'] = 1 + +    # Enable private VLAN proxy ARP on this interface +    if conf.exists('ip proxy-arp-pvlan'): +        eth['ip_proxy_arp_pvlan'] = 1 + +    # Media Access Control (MAC) address +    if conf.exists('mac'): +        eth['mac'] = conf.return_value('mac') + +    # Maximum Transmission Unit (MTU) +    if conf.exists('mtu'): +        eth['mtu'] = int(conf.return_value('mtu')) + +    # re-set configuration level and retrieve vif-s interfaces +    conf.set_level(cfg_base) +    # get vif-s interfaces (currently effective) - to determine which vif-s +    # interface is no longer present and needs to be removed +    eff_intf = conf.list_effective_nodes('vif-s') +    act_intf = conf.list_nodes('vif-s') +    eth['vif_s_remove'] = list_diff(eff_intf, act_intf) + +    if conf.exists('vif-s'): +        for vif_s in conf.list_nodes('vif-s'): +            # set config level to vif-s interface +            conf.set_level(cfg_base + ' vif-s ' + vif_s) +            eth['vif_s'].append(vlan_to_dict(conf)) + +    # re-set configuration level and retrieve vif-s interfaces +    conf.set_level(cfg_base) +    # Determine vif interfaces (currently effective) - to determine which +    # vif interface is no longer present and needs to be removed +    eff_intf = conf.list_effective_nodes('vif') +    act_intf = conf.list_nodes('vif') +    eth['vif_remove'] = list_diff(eff_intf, act_intf) + +    if conf.exists('vif'): +        for vif in conf.list_nodes('vif'): +            # set config level to vif interface +            conf.set_level(cfg_base + ' vif ' + vif) +            eth['vif'].append(vlan_to_dict(conf)) + +    return eth + + +def verify(eth): +    conf = Config() +    # some options can not be changed when interface is enslaved to a bond +    for bond in conf.list_nodes('interfaces bonding'): +        if conf.exists('interfaces bonding ' + bond + ' member interface'): +                if eth['name'] in conf.return_values('interfaces bonding ' + bond + ' member interface'): +                    if eth['disable']: +                        raise ConfigError('Can not disable interface {} which is a member of {}').format(eth['intf'], bond) + +                    if eth['address']: +                        raise ConfigError('Can not assign address to interface {} which is a member of {}').format(eth['intf'], bond) + + +    return None + + +def generate(eth): +    import pprint +    pprint.pprint(eth) +    return None + + +def apply(eth): +    e = EthernetIf(eth['intf']) +    # update interface description used e.g. within SNMP +    e.ifalias = eth['description'] + +    # +    # missing DHCP/DHCPv6 options go here +    # + +    # ignore link state changes +    e.link_detect = eth['disable_link_detect'] +    # configure ARP cache timeout in milliseconds +    e.arp_cache_tmp = eth['ip_arp_cache_tmo'] +    # Enable proxy-arp on this interface +    e.proxy_arp = eth['ip_proxy_arp'] +    # Enable private VLAN proxy ARP on this interface +    e.proxy_arp_pvlan = eth['ip_proxy_arp_pvlan'] + +    # Change interface MAC address +    if eth['mac']: +        e.mac = eth['mac'] + +    # Maximum Transmission Unit (MTU) +    e.mtu = eth['mtu'] + +    # Configure interface address(es) +    # - not longer required addresses get removed first +    # - newly addresses will be added second +    for addr in eth['address_remove']: +        e.del_addr(addr) +    for addr in eth['address']: +        e.add_addr(addr) + +    # Enable/Disable interface +    if eth['disable']: +        e.state = 'down' +    else: +        e.state = 'up' + +    # remove no longer required service VLAN interfaces (vif-s) +    for vif_s in eth['vif_s_remove']: +        e.del_vlan(vif_s) + +    # create service VLAN interfaces (vif-s) +    for vif_s in eth['vif_s']: +        s_vlan = e.add_vlan(vif_s['id'], ethertype=vif_s['ethertype']) +        apply_vlan_config(s_vlan, vif_s) + +        # remove no longer required client VLAN interfaces (vif-c) +        # on lower service VLAN interface +        for vif_c in vif_s['vif_c_remove']: +            s_vlan.del_vlan(vif_c) + +        # create client VLAN interfaces (vif-c) +        # on lower service VLAN interface +        for vif_c in vif_s['vif_c']: +            c_vlan = s_vlan.add_vlan(vif_c['id']) +            apply_vlan_config(c_vlan, vif_c) + +    # remove no longer required VLAN interfaces (vif) +    for vif in eth['vif_remove']: +        e.del_vlan(vif) + +    # create VLAN interfaces (vif) +    for vif in eth['vif']: +        vlan = e.add_vlan(vif['id']) +        apply_vlan_config(vlan, vif) + +    return None + +if __name__ == '__main__': +    try: +        c = get_config() +        verify(c) +        generate(c) +        apply(c) +    except ConfigError as e: +        print(e) +        exit(1) | 
