def _buildNexthopGroups(self): groups = self.config_.nexthop_groups for name, data in groups.iteritems(): if data.type not in NEXTHOP_GROUP_TYPE: sys.stderr.write('Unknown nexthop group type="%s"' % data.type) continue t = data.type.lower() group = eossdk.NexthopGroup(name, NEXTHOP_GROUP_TYPE.get(t)) # Set common parameters for i, dst in enumerate(data.dst_ips): ip = get_ip_addr(dst) if ip is not None: print 'Adding IP' group.destination_ip_set(i, ip) if t == 'ipinip' or t == 'gre': if data.src_intf: if self.intf_mgr.exists(eossdk.IntfId(data.src_intf)): group.source_intf_is(eossdk.IntfId(data.src_intf)) elif data.src_ips: pass # not yet supported elif t == 'mpls': sys.stderr.write('MPLS nexthop-groups are not yet supported\n') # Set the nexthop group print 'Setting nexthop group:', name self.nexthop_group_mgr.nexthop_group_set(group)
def interface_validate(self, interface, operation, direction): """An interface has been specified so verify that it exists and is usable. Also check that the accompanying parameters are valid. If both true then the ACL can be attached/detached from the interface so return the interface id. If not, return None so processing stops before attempting to process the potentially large rules description file.""" # Verify interface exists try: intf_id = eossdk.IntfId(str(interface)) except eossdk.NoSuchInterfaceError: sys.stderr.write("Interface %s does not exist\n" % interface) return None if direction.lower() != "in" and direction.lower() != "out" : sys.stderr.write("Direction must be 'in' or 'out'," " i.e. not '%s'\n" % direction) return None if operation.lower() != "attach" and operation.lower() != "detach" : sys.stderr.write("Operation must be 'attach' or 'detach'," " i.e. not '%s'\n" % operation) return None return intf_id
def on_readable(self, fd): # Handle input on stdin of the format: # NAME (add|delete) IPADDR INTERFACE # and adds/deletes a flow that matches on that destination ip address # and outputs that flow on the given interface buf = os.read(fd, 4096).strip() if not buf: self.agentMgr_.exit() for line in buf.split("\n"): if not line: continue m = re.search("(\S+) (add|delete) (\d+.\d+.\d+.\d+) +(\S+)", line) if not m: print "Could not match line:", line continue name = m.group(1) operation = m.group(2) if operation == "add": match = createMatch(ipDst=m.group(3), ipDstMask="255.255.255.255") outputIntf = eossdk.IntfId(m.group(4)) action = createAction(outputIntfs=[outputIntf]) priority = 100 entry = eossdk.FlowEntry(name, match, action, priority) self.directFlowMgr_.flow_entry_set(entry) else: assert operation == "delete" self.directFlowMgr_.flow_entry_del(name)
def resolve_egress_tunnel(self, tunnel): self.tracer.trace8("Resolve the nexthop IP %s to an ethernet address" % tunnel.nexthop_ip) neighbor_key = eossdk.NeighborKey(eossdk.IpAddr(tunnel.nexthop_ip), eossdk.IntfId()) neighbor_entry = self.neighbor_table_mgr.neighbor_entry_status( neighbor_key) if neighbor_entry == eossdk.NeighborEntry(): self.tracer.trace8("Checking static ARP entries") neighbor_entry = self.neighbor_table_mgr.neighbor_entry( neighbor_key) if neighbor_entry == eossdk.NeighborEntry(): self.tracer.trace0("IP address %r has no ARP entry" % tunnel.nexthop_ip) assert False, "Unlearned nexthop IP %s" % tunnel.nexthop_ip nexthop_eth_addr = neighbor_entry.eth_addr() self.tracer.trace5("IP %s lives on %s" % (tunnel.nexthop_ip, nexthop_eth_addr.to_string())) tunnel.nexthop_eth_addr = nexthop_eth_addr.to_string() self.tracer.trace8("Now resolving that MAC entry to an interface.") # TODO: Is this necessary if we send it out of the "fabric" # interface? vlan_id = 1 mac_entry = self.mac_table_mgr.mac_entry(vlan_id, nexthop_eth_addr) if mac_entry.intf() == eossdk.IntfId(): self.tracer.trace0("Mac entry %r not on any interface" % tunnel.nexthop_eth_addr) assert False, "Unlearned nexthop MAC %s" % tunnel.nexthop_eth_addr intf = mac_entry.intf().to_string() # Convert the interface names to the kernel interface names intf = intf.replace("Ethernet", "et") intf = intf.replace("Port-Channel", "po") self.tracer.trace5("MAC entry %s is learned on inteface %r" % (tunnel.nexthop_eth_addr, intf)) tunnel.egress_intf = intf self.tracer.trace8("Looking up that interface's MAC address") egress_eth_addr = self.eth_intf_mgr.eth_addr(mac_entry.intf()) if egress_eth_addr == eossdk.EthAddr(): assert False, "Interface %s has no MAC address" % intf self.tracer.trace5("Intf %s has MAC address %s" % (intf, egress_eth_addr.to_string())) tunnel.egress_intf_eth_addr = egress_eth_addr.to_string()
def __init__(self, agentMgr, intfMgr, interfaceName): print "This program controls the admin enabled state of the given interface" print " - 'shutdown' will disable the interface" print " - any other text will enable the interface" print " - an empty line will quit this program" self.agentMgr_ = agentMgr self.intfMgr_ = intfMgr self.intfObj_ = eossdk.IntfId(interfaceName) eossdk.AgentHandler.__init__(self, agentMgr) eossdk.FdHandler.__init__(self) self.eventCount = 0
def _applyToInterfaces(self): interface_policy = self.config_.interface_policy for intf_name, data in interface_policy.iteritems(): policy_map_key = eossdk.PolicyMapKey(data.policy, eossdk.POLICY_FEATURE_PBR) intf_id = eossdk.IntfId(intf_name) if self.intf_mgr.exists(intf_id): print 'Interface %s exists, applying policy' % intf_id.to_string() self.policy_map_mgr.policy_map_apply( policy_map_key, intf_id, eossdk.ACL_IN, True) else: print 'Interface %s does not exist' % intf_id.to_string() print 'Finished applying policy'
def on_route_set(self, route): self.tracer.trace0("Last added hardware route entry %s" % route.route_key().prefix().to_string()) syslog.syslog("Last Added Route %s" % route.route_key().prefix().to_string()) cli = "show ip bgp %s" % route.route_key().prefix().to_string() route_detail = self.eapi_execute(cli) if self.community_list_check(route_detail): self.update_acl(route.route_key().prefix().to_string()) self.aclMgr_.acl_commit() syslog.syslog("ACL Commited") #for acl_rule in self.aclMgr_.acl_rule_ip_iter(self.aclKey): # syslog.syslog("%s"% (acl_rule[1].to_string(),)) if self.aclMgr_.acl_exists(self.aclKey): syslog.syslog("ACL Key Created") # Now build the class map for that ACL and commit it self.classMapKey = eossdk.PolicyMapKey( REDIRECTCLASS, eossdk.POLICY_FEATURE_PBR) self.class_map = eossdk.ClassMap(self.classMapKey) self.classMapRule = eossdk.ClassMapRule(self.aclKey) self.class_map.rule_set(10, self.classMapRule) self.classMapMgr_.class_map_is(self.class_map) self.cm = self.classMapMgr_.class_map(self.classMapKey) syslog.syslog("Set class map %s with %d rules" % (REDIRECTCLASS, len(self.cm.rules()))) # Build the nexthop group that will setup the GRE tunnel self.nhg = eossdk.NexthopGroup(REDIRECTNHG, eossdk.NEXTHOP_GROUP_GRE) self.nhgEntry1 = eossdk.NexthopGroupEntry( eossdk.IpAddr(NHGDSTPREFIX)) self.nhg.nexthop_set(0, self.nhgEntry1) self.nhg.source_ip_is(eossdk.IpAddr(NHGSRCPREFIX)) self.nexthopGroupMgr_.nexthop_group_set(self.nhg) # Add the policy map rule matching our class map and tunnel the traffic self.policyMapKey = eossdk.PolicyMapKey( REDIRECTPOLICY, eossdk.POLICY_FEATURE_PBR) self.policy_map = eossdk.PolicyMap(self.policyMapKey) self.policyMapRule = eossdk.PolicyMapRule(self.classMapKey) self.policyMapAction = eossdk.PolicyMapAction( eossdk.POLICY_ACTION_NEXTHOP_GROUP) self.policyMapAction.nexthop_group_name_is(REDIRECTNHG) self.policyMapRule.action_set(self.policyMapAction) self.policy_map.rule_set(1, self.policyMapRule) self.policyMapMgr_.policy_map_is(self.policy_map) self.policyMapMgr_.policy_map_apply( self.policyMapKey, eossdk.IntfId(INTERFACENAME), eossdk.ACL_IN, True) syslog.syslog("Finished applying policy") else: syslog.syslog("ACL Key Not Created")
def on_initialized(self): """ Update our configured egress tunnels. Start all tunnels as alive, with a last_update_time of now + any grace period. Calculate the output interfaces for each tunnel based off of that tunnel's nexthop MAC address. """ self.initialized = True self.tracer.trace2("Looking up the IP address for interface " + self.src_intf) src_ips = self.ip_intf_mgr.ip_addrs(eossdk.IntfId(self.src_intf)) if not src_ips: assert False, "No IP addresses assigned to %s" % self.src_intf self.src_ip = src_ips[0].addr().to_string() self.tracer.trace2("Using src IP address " + self.src_ip) self.tracer.trace2("Create the socket that receives remote probes") self.rx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.rx_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.rx_sock.bind((self.src_ip, UDP_PORT)) self.rx_sock.setblocking(0) self.watch_readable(self.rx_sock.fileno(), True) self.resolve_config()