def create_loopback_interface(obj, params): name = None mac_str = None mac = None try: name = obj.get_attr_data('if/interfaces/interface/name') mac_str = obj.get_attr_data( 'dell-if/if/interfaces/interface/phys-address') except: pass if name is None: nas_if.log_err("Failed to create interface without name") return False nas_if.log_info("interface name is" + str(name)) lst = dn_base_ip_tool.get_if_details(name) if (len(lst)) > 0: nas_if.log_err("Interface already exists" + str(name)) return False if mac_str is None: mac_str = ma.get_offset_mac_addr(ma.get_base_mac_addr(), 0) rc = dn_base_ip_tool.create_loopback_if(name, mac=mac_str) if rc: nas_if.log_info("loopback interface is created" + str(name)) rc = set_loopback_interface(obj) if_index = ifindex_utils.if_nametoindex(name) obj.add_attr(nas_comm.yang.get_value('if_index', 'attr_name'), if_index) params['change'] = obj.get() return rc
def process_vrf_intf_config(is_add, if_name, vrf_name): res = [] if_index = 0 v_mac_str = None # Remove VRF association from L3 intf if is_add is False: # For intf removal from default VRF case, no action required # since there is no dedicated router interface (MAC-VLAN interface). if vrf_name == _default_vrf_name: return (True,if_name,if_index, v_mac_str) if vrf_name != _mgmt_vrf_name: if run_command(['sysctl', '-w', 'net.ipv6.conf.'+if_name+'.disable_ipv6=0'], res) != 0: return (False,if_name,if_index, v_mac_str) # Delete the MAC-VLAN interface and also, delete the associated IP table rules. if_name = 'v-'+if_name cmd = [iplink_cmd, 'netns', 'exec', vrf_name, 'ip', 'link', 'delete', if_name] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) process_vrf_ip_nat_config(is_add, vrf_name, if_name, 'iptables') process_vrf_ip_nat_config(is_add, vrf_name, if_name, 'ip6tables') else: cmd = [iplink_cmd, 'netns', 'exec', vrf_name, 'ip', 'link', 'set', if_name, 'netns', '1'] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) # Disable local network (127/8) routing. cmd = ['sysctl', '-w', 'net.ipv4.conf.'+if_name+'.route_localnet=0'] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) process_vrf_ip_nat_config(is_add, vrf_name, if_name, 'iptables') process_vrf_ip_nat_config(is_add, vrf_name, if_name, 'ip6tables') return (True,if_name,if_index, v_mac_str) # For default VRF, use the interface MAC # For non-default VRF, use the base MAC as router interface MAC, # if there is a need for a seperate MAC, will have to allocate # and use it on the router interface. # For default VRF case, just return the if-index and MAC address from # the interface present in the default VRF. if vrf_name == _default_vrf_name: # L3 intf with default VRF binding cmd = [iplink_cmd, 'link', 'show', 'dev', if_name] res = [] if run_command(cmd, res) != 0: return (False,if_name,0,None) if_index = int(res[0].split(':')[0]) # In the ip link interface output, 2nd line and 5th field # is always MAC address. v_mac_str = str(res[1].split(' ')[5]) return (True,if_name,if_index,v_mac_str) v_mac_str = ma.get_offset_mac_addr(ma.get_base_mac_addr(), 0) if vrf_name == _mgmt_vrf_name: # @@TODO Migrate this to MAC-VLAN approach - L3 intf with management VRF binding cmd = [iplink_cmd, 'link', 'set', 'dev', if_name, 'netns', vrf_name] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) cmd = [iplink_cmd, '-n', vrf_name, 'link', 'show', 'dev', if_name] res = [] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) # In the ip link show interface output, always the first field is interface index. if_index = int(res[0].split(':')[0]) else: # L3 intf with non-default VRF binding intf_up = None # Create MAC-VLAN interface on L3 interface res = [] cmd = [iplink_cmd, 'link', 'show', 'dev', if_name] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) # Check whether the lower layer interface is admin up, if admin up, # update on the router interface (MAC-VLAN) interface as well. try: # 2nd field <BROADCAST,MULTICAST,UP,LOWER_UP> is admin up/down in the interface show if 'UP' in (res[0].split(' ')[2]): intf_up = 'UP' except: pass # For loopback interface, dont assign the MAC, kernel assigned random is fine, # there seems to be no use of this loopback MAC in the L3 packets. # @@TODO Double check if there is a real use-case for loopback MAC. if if_name[0:2] == 'lo': cmd = [iplink_cmd, 'link', 'add', 'link', if_name, 'v-'+if_name, 'type', 'macvlan',\ 'mode', 'bridge'] else: cmd = [iplink_cmd, 'link', 'add', 'link', if_name, 'v-'+if_name, 'address', v_mac_str, 'type', 'macvlan',\ 'mode', 'bridge'] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) # L3 intf with VRF bind cmd = [iplink_cmd, 'link', 'set', 'dev', 'v-'+if_name, 'netns', vrf_name] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) if run_command(['sysctl', '-w', 'net.ipv6.conf.'+if_name+'.disable_ipv6=1'], res) != 0: return (False,if_name,if_index, v_mac_str) if_name = 'v-'+if_name # Get the if-index from MAC-VLAN interface # Enable local network (127/8) routing. if intf_up == 'UP': cmd = [iplink_cmd, '-n', vrf_name, 'link', 'set', 'dev', if_name, 'up'] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) cmd = [iplink_cmd, '-n', vrf_name, 'link', 'show', 'dev', if_name] res = [] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) # In the ip link show interface output, always the first field is interface index. if_index = int(res[0].split(':')[0]) cmd = [iplink_cmd, 'netns', 'exec', vrf_name, 'sysctl', '-w',\ 'net.ipv4.conf.'+if_name+'.route_localnet=1'] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) # DROP if local network packets are going out of eth0 # iptables -I OUTPUT -o eth0 -d loopback/8 -j DROP cmd = [iplink_cmd, 'netns', 'exec', vrf_name, 'iptables', '-I', 'OUTPUT',\ '-o', if_name, '-d', 'loopback/8', '-j', 'DROP'] if run_command(cmd, res) != 0: return (False,if_name,if_index, v_mac_str) # @@TODO Put the similar rule for IPv6 reserved address also. # Once the default NAT rules are created, it will be there until the management # net_ns is deleted process_vrf_ip_nat_config(is_add, vrf_name, if_name, 'iptables') process_vrf_ip_nat_config(is_add, vrf_name, if_name, 'ip6tables') return (True,if_name,if_index, v_mac_str)