예제 #1
0
   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)
예제 #2
0
   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
예제 #3
0
 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)
예제 #4
0
    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()
예제 #5
0
 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
예제 #6
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'
예제 #7
0
    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")
예제 #8
0
    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()