def _handle_PacketIn(event): global server_index packet = event.parsed # Only handle IPv4 flows if (not event.parsed.find("ipv4")): return EventContinue msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) # Only handle traffic destined to virtual IP if (msg.match.nw_dst != virtual_ip): return EventContinue # Round robin selection of servers index = server_index % total_servers print index selected_server_ip = server[index]['ip'] selected_server_mac = server[index]['mac'] selected_server_outport = server[index]['outport'] server_index += 1 # Setup route to server msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, selected_server_ip)) msg.actions.append(of.ofp_action_output(port=selected_server_outport)) event.connection.send(msg) # Setup reverse route from server reverse_msg = of.ofp_flow_mod() reverse_msg.buffer_id = None reverse_msg.in_port = selected_server_outport reverse_msg.match = of.ofp_match() reverse_msg.match.dl_src = selected_server_mac reverse_msg.match.nw_src = selected_server_ip reverse_msg.match.tp_src = msg.match.tp_dst reverse_msg.match.dl_dst = msg.match.dl_src reverse_msg.match.nw_dst = msg.match.nw_src reverse_msg.match.tp_dst = msg.match.tp_src reverse_msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac)) reverse_msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, virtual_ip)) reverse_msg.actions.append(of.ofp_action_output(port=msg.in_port)) event.connection.send(reverse_msg) return EventHalt
def _handle_PacketIn(event): global server_index packet = event.parsed # First make sure the packet is addressed using IPv4 if (not event.parsed.find("ipv4")): return EventContinue msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) # If the ip matches controller virtual ip then continue if (msg.match.nw_dst != controllerip): return EventContinue # Employing round robin algorithm here index = server_index % total_servers print index selected_server_ip = server[index]['ip'] selected_server_mac = server[index]['mac'] selected_server_outport = server[index]['outport'] server_index += 1 # Setup route to server msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, selected_server_ip)) msg.actions.append(of.ofp_action_output(port=selected_server_outport)) event.connection.send(msg) # Once the last server is reached, reverse the route reverse_msg = of.ofp_flow_mod() reverse_msg.buffer_id = None reverse_msg.in_port = selected_server_outport reverse_msg.match = of.ofp_match() reverse_msg.match.dl_src = selected_server_mac reverse_msg.match.nw_src = selected_server_ip reverse_msg.match.tp_src = msg.match.tp_dst reverse_msg.match.dl_dst = msg.match.dl_src reverse_msg.match.nw_dst = msg.match.nw_src reverse_msg.match.tp_dst = msg.match.tp_src reverse_msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, controllermac)) reverse_msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, controllerip)) reverse_msg.actions.append(of.ofp_action_output(port=msg.in_port)) event.connection.send(reverse_msg) return EventHalt
def packet_handler(event): global server_no packet = event.parsed # Only handle traffic destined to virtual IP if (not event.parsed.find("ipv4")): return event_cont message = of.ofp_flow_mod() message.match = of.ofp_match.from_packet(packet) # Handing requests routed to the Load Balancer Ip if (message.match.nw_dst != load_balancer_hardcoded_ip): return event_cont # Random selection of servers iterator = random.randint(0, server_no - 1) print iterator serverip = topology_server[iterator]['ip'] selected_server_mac = topology_server[iterator]['mac'] server_output = topology_server[iterator]['outport'] # Route followed to server message.buffer_id = event.ofp.buffer_id message.in_port = event.port message.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) message.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, serverip)) message.actions.append(of.ofp_action_output(port=server_output)) event.connection.send(message) # Route from server to load balancer reply = of.ofp_flow_mod() reply.buffer_id = None reply.in_port = server_output reply.match = of.ofp_match() reply.match.dl_src = selected_server_mac reply.match.nw_src = serverip reply.match.tp_src = message.match.tp_dst reply.match.dl_dst = message.match.dl_src reply.match.nw_dst = message.match.nw_src reply.match.tp_dst = message.match.tp_src reply.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac)) reply.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, load_balancer_hardcoded_ip)) reply.actions.append(of.ofp_action_output(port=message.in_port)) event.connection.send(reply) return EventHalt
def _handle_PacketIn (event): global server_index packet = event.parsed # Only handle IPv4 flows if (not event.parsed.find("ipv4")): return EventContinue msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) # Only handle traffic destined to virtual IP if (msg.match.nw_dst != virtual_ip): return EventContinue # Round robin selection of servers index = server_index % total_servers print index selected_server_ip = server[index]['ip'] selected_server_mac = server[index]['mac'] selected_server_outport = server[index]['outport'] server_index += 1 # Setup route to server msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port msg.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, selected_server_ip)) msg.actions.append(of.ofp_action_output(port = selected_server_outport)) event.connection.send(msg) # Setup reverse route from server reverse_msg = of.ofp_flow_mod() reverse_msg.buffer_id = None reverse_msg.in_port = selected_server_outport reverse_msg.match = of.ofp_match() reverse_msg.match.dl_src = selected_server_mac reverse_msg.match.nw_src = selected_server_ip reverse_msg.match.tp_src = msg.match.tp_dst reverse_msg.match.dl_dst = msg.match.dl_src reverse_msg.match.nw_dst = msg.match.nw_src reverse_msg.match.tp_dst = msg.match.tp_src reverse_msg.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac)) reverse_msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, virtual_ip)) reverse_msg.actions.append(of.ofp_action_output(port = msg.in_port)) event.connection.send(reverse_msg) return EventHalt
def CreateActions(self, actions, entry, outbound): if outbound: actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external)) actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, NAT_IP_EXTERNAL)) actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC, entry["natport"])) actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, GetMACFromIP(entry["extip"]))) actions.append(of.ofp_action_output(port=self.port_external)) else: actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external)) actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, entry["int"])) actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, entry["intip"])) actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_DST, entry["intport"])) actions.append(of.ofp_action_output(port=GetPortFromIP(entry["intip"])))
def _match_action(self,msg): if len(self.actions) == 1 and self.actions[0] == "" : return for action in self.actions: action_name = action.split('=')[0] if action_name != "STRIP_VLAN": action_argu = action.split('=')[1] if(action_name == "OUTPUT"): msg.actions.append(of.ofp_action_output(port = int(action_argu))) elif(action_name == "ENQUEUE"): port = action_argu.split(':')[0] queue_id = action_argu.split(':')[1] msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id))) elif(action_name == "STRIP_VLAN"): msg.actions.append(of.ofp_action_strip_vlan()) elif(action_name == "SET_VLAN_VID"): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(action_argu))) elif(action_name == "SET_VLAN_PCP"): msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(action_argu))) elif(action_name == "SET_DL_SRC"): msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(action_argu))) elif(action_name == "SET_DL_DST"): msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(action_argu))) elif(action_name == "SET_NW_TOS"): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(action_argu))) elif(action_name == "SET_NW_SRC"): msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(action_argu))) elif(action_name == "SET_NW_DST"): msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(action_argu))) elif(action_name == "SET_TP_SRC"): msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(action_argu))) elif(action_name == "SET_TP_DST"): msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(action_argu)))
def Round_Robin(event): global ServerUsed global server_virtual_ip global server_virtual_mac packet = event.parsed msg_to_server = of.ofp_flow_mod() msg_to_server.match = of.ofp_match.from_packet(packet) if (event.parsed.find("ipv4")) and (msg_to_server.match.nw_dst == server_virtual_ip): print ('Server in Service => Server :', ServerUsed) server_ip = serverList[ServerUsed] ['ip'] print ('With IP => ServerIP = :', server_ip) server_mac= serverList[ServerUsed]['mac'] server_outport= serverList[ServerUsed]['port'] # Setup route to server # setup_route_to_server(event,msg_to_server,server_mac,server_ip,server_outport) msg_to_server.buffer_id = event.ofp.buffer_id msg_to_server.in_port = event.port msg_to_server.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, server_mac)) msg_to_server.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, server_ip)) msg_to_server.actions.append(of.ofp_action_output(port = server_outport)) event.connection.send(msg_to_server) # Setup reverse route from server # setup_route_from_server(event,msg_to_server,server_mac,server_ip,server_outport) msg_from_server = of.ofp_flow_mod()
def forward_pkt_to_next_hop(self, packet, match, event, route, justSend = False): ipp = packet.find("ipv4") if ipp.ttl <= 1: return self.send_icmp_ttl_exceed(packet, match, event) nextHopIp = route.nextHopIpAddr if str(route.nextHopIpAddr) not in self.myips else match.nw_dst if not justSend and nextHopIp not in self.arpTable: self.send_arp_request(event, route, packet, match, nextHopIp) q = self.queuedMsgForArp.get(nextHopIp, []) q.append([packet, match, event, route]) self.queuedMsgForArp[nextHopIp] = q return if nextHopIp not in self.arpTable: log.info("%s: mac for nexthopip(%s) is not present in arptable(%s). returning"%(self.name, nextHopIp, self.arpTable)) nextHopAddr = self.arpTable[nextHopIp] msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) #import pdb; pdb.set_trace() log.debug("%s: intf: %s, ,port2Mac: %s, intf2Port: %s, dst: %s", self.name, route.intf, self.port2Mac, self.intf2Port, nextHopAddr) #msg.actions.append(action) action = of.ofp_action_dl_addr() msg.actions.append(action.set_dst(nextHopAddr)) msg.actions.append(action.set_src(self.port2Mac[self.intf2Port[route.intf]])) msg.actions.append(of.ofp_action_output(port = self.intf2Port[route.intf])) msg.data = event.ofp event.connection.send(msg)
def alter_ethernet_address(addr: str, src: bool) -> "Action": """ if src is true, the src is altered. if src is false, the destination is altered. """ type = 4 if src else 5 return of.ofp_action_dl_addr(type, addr)
def forward_pkt_to_next_hop(self, packet, match, event, route, justSend=False): ipp = packet.find("ipv4") if ipp.ttl <= 1: return self.send_icmp_ttl_exceed(packet, match, event) nextHopIp = route.nextHopIpAddr if str( route.nextHopIpAddr) not in self.myips else match.nw_dst if not justSend and nextHopIp not in self.arpTable: self.send_arp_request(event, route, packet, match, nextHopIp) q = self.queuedMsgForArp.get(nextHopIp, []) q.append([packet, match, event, route]) self.queuedMsgForArp[nextHopIp] = q return if nextHopIp not in self.arpTable: log.info( "%s: mac for nexthopip(%s) is not present in arptable(%s). returning" % (self.name, nextHopIp, self.arpTable)) nextHopAddr = self.arpTable[ nextHopIp] #ROUTERS_IP_2_PORT[str(route.nextHopIpAddr)] if str(route.nextHopIpAddr) not in self.myips or nextHopIp not in self.arpTable else self.arpTable[nextHopIp] # ipp.ttl = ipp.ttl - 1 # # packet_in = event.ofp # # e = packet#pkt.ethernet() # e.src = self.port2Mac[self.intf2Port[route.intf]] # e.dst = nextHopAddr # # e.type = e.IP_TYPE # # # e.payload = ipp # # msg = of.ofp_packet_out() # msg.actions.append(of.ofp_action_output(port = self.intf2Port[route.intf])) # msg.data = e#vent.ofp # # msg.in_port = event.port # event.connection.send(msg) # return msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) #import pdb; pdb.set_trace() log.debug("%s: intf: %s, ,port2Mac: %s, intf2Port: %s, dst: %s", self.name, route.intf, self.port2Mac, self.intf2Port, nextHopAddr) #msg.actions.append(action) action = of.ofp_action_dl_addr() msg.actions.append(action.set_dst(nextHopAddr)) msg.actions.append( action.set_src(self.port2Mac[self.intf2Port[route.intf]])) msg.actions.append( of.ofp_action_output(port=self.intf2Port[route.intf])) msg.data = event.ofp event.connection.send(msg)
def send_ofmod_modify_forward(self, _called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst, fport, duration): msg = of.ofp_flow_mod() msg.priority = 0x7000 msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4) msg.match.nw_src = IPAddr(nw_src) msg.match.nw_dst = IPAddr(nw_dst) msg.match.nw_proto = 17 #UDP if tp_dst != None: msg.match.tp_dst = int(tp_dst) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] if _called_from == 'packet_in': msg.buffer_id = event.ofp.buffer_id msg.actions.append( of.ofp_action_nw_addr(nw_addr=IPAddr(new_dst), type=7)) msg.actions.append( of.ofp_action_dl_addr(dl_addr=EthAddr(new_dl_dst), type=5)) msg.actions.append(of.ofp_action_output(port=fport)) conn.send(msg) print '\nsend_ofmod_modify_forward to sw_dpid=%s' % conn.dpid print 'wcs: src_ip=%s, dst_ip=%s, tp_dst=%s' % (nw_src, nw_dst, tp_dst) print 'acts: new_dst=%s, new_dl_dst=%s, fport=%s\n' % ( new_dst, new_dl_dst, fport)
def _match_action(self,msg): if(self.actions == "OUTPUT"): msg.actions.append(of.ofp_action_output(port = int(self.actions_argu))) elif(self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id))) elif(self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif(self.actions == "set-vlan-id"): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu))) elif(self.actions == "set-vlan-priority"): msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu))) elif(self.actions == "SET_DL_SRC"): msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_DL_DST"): msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_NW_TOS"): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu))) elif(self.actions == "SET_NW_SRC"): msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_NW_DST"): msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_TP_SRC"): msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu))) elif(self.actions == "SET_TP_DST"): msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu)))
def CreateActions(self, actions, entry, outbound): if outbound: actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external)) actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, NAT_IP_EXTERNAL)) actions.append( of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC, entry["natport"])) actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, GetMACFromIP(entry["extip"]))) actions.append(of.ofp_action_output(port=self.port_external)) else: actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external)) actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, entry["int"])) actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, entry["intip"])) actions.append( of.ofp_action_tp_port(of.OFPAT_SET_TP_DST, entry["intport"])) actions.append( of.ofp_action_output(port=GetPortFromIP(entry["intip"])))
def send_ofmod_modify_forward (_called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst,o_port, duration): msg = of.ofp_flow_mod() msg.priority = 0x7000 msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4) msg.match.nw_src = IPAddr(nw_src) msg.match.nw_dst = IPAddr(nw_dst) msg.match.nw_proto = 17 #UDP if tp_dst != None: msg.match.tp_dst = int(tp_dst) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] if _called_from == 'packet_in': msg.buffer_id = event.ofp.buffer_id msg.actions.append(of.ofp_action_nw_addr(nw_addr = IPAddr(new_dst), type=7)) msg.actions.append(of.ofp_action_dl_addr(dl_addr = EthAddr(new_dl_dst), type=5)) msg.actions.append(of.ofp_action_output(port = o_port)) conn.send(msg) print "\nFrom dpid: ", conn.dpid, "send_ofmod_modify_forward", "src_ip: ",nw_src, print " dst_ip: ",nw_dst," tp_dst: ",tp_dst," new_dst_ip: ",new_dst, " new_dst_mac: ", new_dl_dst, " fport: ", o_port, " is sent\n"
def send_ofmod_modify_forward(self, _called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst,fport, duration): msg = of.ofp_flow_mod() msg.priority = 0x7000 msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4) msg.match.nw_src = IPAddr(nw_src) msg.match.nw_dst = IPAddr(nw_dst) msg.match.nw_proto = 17 #UDP if tp_dst != None: msg.match.tp_dst = int(tp_dst) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] if _called_from == 'packet_in': msg.buffer_id = event.ofp.buffer_id msg.actions.append(of.ofp_action_nw_addr(nw_addr = IPAddr(new_dst), type=7)) msg.actions.append(of.ofp_action_dl_addr(dl_addr = EthAddr(new_dl_dst), type=5)) msg.actions.append(of.ofp_action_output(port = fport)) conn.send(msg) print '\nsend_ofmod_modify_forward to sw_dpid=%s' % conn.dpid print 'wcs: src_ip=%s, dst_ip=%s, tp_dst=%s' % (nw_src,nw_dst,tp_dst) print 'acts: new_dst=%s, new_dl_dst=%s, fport=%s\n' % (new_dst, new_dl_dst, fport)
def send_ofmod_modify_forward (self, _called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst, o_port, duration): msg = of.ofp_flow_mod() msg.priority = 0x7000 msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4) msg.match.nw_src = IPAddr(nw_src) msg.match.nw_dst = IPAddr(nw_dst) if tp_dst != None: msg.match.nw_proto = 17 #UDP msg.match.tp_dst = int(tp_dst) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] if _called_from == 'packet_in': msg.buffer_id = event.ofp.buffer_id msg.actions.append(of.ofp_action_nw_addr(nw_addr = IPAddr(new_dst), type=7)) msg.actions.append(of.ofp_action_dl_addr(dl_addr = EthAddr(new_dl_dst), type=5)) msg.actions.append(of.ofp_action_output(port = o_port)) conn.send(msg) print "\nFrom dpid: ", conn.dpid, "send_ofmod_modify_forward", "src_ip: ", \ nw_src," dst_ip: ",nw_dst," tp_dst: ",tp_dst," new_dst_ip: ",new_dst, \ " new_dst_mac: ", new_dl_dst, " fport: ", o_port, " is sent\n"
def _match_action(self, msg): if len(self.actions) == 1 and self.actions[0] == "": return for action in self.actions: action_name = action.split('=')[0] if action_name != "STRIP_VLAN": action_argu = action.split('=')[1] if (action_name == "OUTPUT"): msg.actions.append(of.ofp_action_output(port=int(action_argu))) elif (action_name == "ENQUEUE"): port = action_argu.split(':')[0] queue_id = action_argu.split(':')[1] msg.actions.append( of.ofp_action_enqueue(port=int(port), queue_id=int(queue_id))) elif (action_name == "STRIP_VLAN"): msg.actions.append(of.ofp_action_strip_vlan()) elif (action_name == "SET_VLAN_VID"): msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=int(action_argu))) elif (action_name == "SET_VLAN_PCP"): msg.actions.append( of.ofp_action_vlan_pcp(vlan_pcp=int(action_argu))) elif (action_name == "SET_DL_SRC"): msg.actions.append( of.ofp_action_dl_addr(type=4, dl_addr=EthAddr(action_argu))) elif (action_name == "SET_DL_DST"): msg.actions.append( of.ofp_action_dl_addr(type=5, dl_addr=EthAddr(action_argu))) elif (action_name == "SET_NW_TOS"): msg.actions.append( of.ofp_action_nw_tos(nw_tos=int(action_argu))) elif (action_name == "SET_NW_SRC"): msg.actions.append( of.ofp_action_nw_addr(type=6, nw_addr=IPAddr(action_argu))) elif (action_name == "SET_NW_DST"): msg.actions.append( of.ofp_action_nw_addr(type=7, nw_addr=IPAddr(action_argu))) elif (action_name == "SET_TP_SRC"): msg.actions.append( of.ofp_action_tp_port(type=9, tp_port=int(action_argu))) elif (action_name == "SET_TP_DST"): msg.actions.append( of.ofp_action_tp_port(type=10, tp_port=int(action_argu)))
def packet_handler (event): global count_server packet = event.parsed # Only handle IPv4 flows if (not event.parsed.find("ipv4")): return event_cont message = of.ofp_flow_mod() message.match = of.ofp_match.from_packet(packet) # Only handle traffic destined to virtual IP if (message.match.nw_dst != load_balancer_hardcoded_ip): return event_cont # Implementing Weighted Round robin Server Selection iterator = count_server % 6 print iterator if(iterator < topology_server[0]['weight']): serverip = topology_server[0]['ip'] selected_server_mac = topology_server[0]['mac'] server_output = topology_server[0]['outport'] elif(iterator < (topology_server[0]['weight']+topology_server[1]['weight'])): serverip = topology_server[1]['ip'] selected_server_mac = topology_server[1]['mac'] server_output = topology_server[1]['outport'] elif(iterator < (server[0]['weight']+server[1]['weight']+server[2]['weight'])): serverip = server[2]['ip'] selected_server_mac = server[2]['mac'] server_output = server[2]['outport'] count_server += 1 # Route followed to server message.buffer_id = event.ofp.buffer_id message.in_port = event.port message.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) message.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, serverip)) message.actions.append(of.ofp_action_output(port = server_output)) event.connection.send(message) # Route from server to load balancer reply = of.ofp_flow_mod() reply.buffer_id = None reply.in_port = server_output reply.match = of.ofp_match() reply.match.dl_src = selected_server_mac reply.match.nw_src = serverip reply.match.tp_src = message.match.tp_dst reply.match.dl_dst = message.match.dl_src reply.match.nw_dst = message.match.nw_src reply.match.tp_dst = message.match.tp_src reply.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, load_balancer_hardcoded_mac)) reply.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, load_balancer_hardcoded_ip)) reply.actions.append(of.ofp_action_output(port = message.in_port)) event.connection.send(reply) return EventHalt
def handle_IPPacket(self, event): is_src_router = (event.ofp.in_port == of.OFPP_LOCAL) if event.parsed.next.srcip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "source ip is not routable" return if event.parsed.src != self.bridge_mac and not self.check_access( event.parsed.src): print "%s is not permmited" % (str(event.parsed.src)) return if event.parsed.next.dstip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "destination is not routable" return is_src_local = event.parsed.next.srcip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.srcip.inNetwork( INIT_SUBNET, INIT_NETMASK) if is_src_local and (event.parsed.next.srcip.toUnsigned( networkOrder=False) & 0x3) == 1: if not self.get_DHCP_mapping().is_valid_mapping( event.parsed.next.srcip, event.parsed.src) and event.parsed.src != self.bridge_mac: print "received packet from unrecorded mac address" return if event.parsed.next.dstip.inNetwork(MULTICAST_SUBNET, MULTICAST_NETMASK): print "multicast" if event.parsed.next.dstip in self.multicast_ip: action = of.ofp_action_output(port=of.OFPP_FLOOD) command = of.OFPFC_ADD self.send_flow_modification(event, command, [action], timeout=30) # check if broadcast. Change nw_dst to 10.2.255.255 if event.parsed.next.dstip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ( (event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x3) == 0x3): print "broadcast IP" nw_new = of.ofp_action_nw_addr() nw_new.type = of.OFPAT_SET_NW_DST nw_new.nw_addr = IPAddr("10.2.255.255") out = of.ofp_action_output( port=of.OFPP_IN_PORT if event.ofp.in_port == 0 else 0) actions = [out, nw_new] command = of.OFPFC_ADD self.send_flow_modification(event, command, actions, timeout=30) dst_port = 0 if event.parsed.next.dstip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ( (event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x01) == 0x01): dst_port = 1 else: dst_port = 0 actions = [] is_dst_local = event.parsed.next.dstip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.dstip.inNetwork( INIT_SUBNET, INIT_NETMASK) if is_dst_local and is_src_local and (dst_port != 0) and (not is_src_router): dst_mac = self.get_DHCP_mapping().get_mac(event.parsed.next.dstip) new_dl_src = of.ofp_action_dl_addr() new_dl_src.type = of.OFPAT_SET_DL_SRC new_dl_src.set_src(self.bridge_mac) actions.append(new_dl_src) new_dl_dst = of.ofp_action_dl_addr() new_dl_dst.type = of.OFPAT_SET_DL_DST new_dl_dst.set_dst(dst_mac) actions.append(new_dl_dst) out = of.ofp_action_output(port=of.OFPP_FLOOD) actions.append(out) if 0 < event.ofp.in_port and event.ofp.in_port < of.OFPP_MAX: out_of_in = of.ofp_action_output(port=of.OFPP_IN_PORT) actions.append(out_of_in) command = of.OFPFC_ADD self.send_flow_modification(event, command, actions, timeout=30)
# Setup route to server setup_route_to_server(event,msg_to_server,server_mac,server_ip,server_outport) # Setup reverse route from server setup_route_from_server(event,msg_to_server,server_mac,server_ip,server_outport) return EventHalt else: return EventContinue def setup_route_to_server(event,msg_to_server,server_mac,server_ip,server_outport): msg_to_server.buffer_id = event.ofp.buffer_id msg_to_server.in_port = event.port msg_to_server.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, server_mac)) msg_to_server.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, server_ip)) msg_to_server.actions.append(of.ofp_action_output(port = server_outport)) event.connection.send(msg_to_server) def setup_route_from_server(event,msg_to_server,server_mac,server_ip,server_outport): global ServerUsed msg_from_server = of.ofp_flow_mod() msg_from_server.buffer_id = None msg_from_server.in_port = server_outport msg_from_server.match = of.ofp_match() msg_from_server.match.dl_src = server_mac msg_from_server.match.nw_src = server_ip msg_from_server.match.tp_src = msg_to_server.match.tp_dst
def handle_IPPacket( self, event ): is_src_router = (event.ofp.in_port == of.OFPP_LOCAL) # @UndefinedVariable if event.parsed.next.srcip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "source ip is not routable" return if event.parsed.src != self.bridge_mac and not self.check_access(event.parsed.src): print "%s is not permmited" % (str(event.parsed.src)) return if event.parsed.next.dstip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "destination is not routable" return is_src_local = event.parsed.next.srcip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.srcip.inNetwork(INIT_SUBNET, INIT_NETMASK) if is_src_local and (event.parsed.next.srcip.toUnsigned(networkOrder=False) & 0x3) == 1: if not self.get_DHCP_mapping().is_valid_mapping(event.parsed.next.srcip, event.parsed.src) and event.parsed.src != self.bridge_mac: print "received packet from unrecorded mac address" return if event.parsed.next.dstip.inNetwork(MULTICAST_SUBNET, MULTICAST_NETMASK): print "multicast" if event.parsed.next.dstip in self.multicast_ip: action = of.ofp_action_output(port=of.OFPP_FLOOD) # @UndefinedVariable command = of.OFPFC_ADD # @UndefinedVariable self.send_flow_modification(event, command, [action], timeout=30) # check if broadcast. Change nw_dst to 10.2.255.255 if event.parsed.next.dstip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ((event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x3) == 0x3): print "broadcast IP" nw_new = of.ofp_action_nw_addr() nw_new.type = of.OFPAT_SET_NW_DST # @UndefinedVariable nw_new.nw_addr = IPAddr("10.2.255.255") out = of.ofp_action_output(port=of.OFPP_IN_PORT if event.ofp.in_port == 0 else 0) # @UndefinedVariable actions = [out, nw_new] command = of.OFPFC_ADD # @UndefinedVariable self.send_flow_modification(event, command, actions, timeout=30) dst_port = 0 if event.parsed.next.dstip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ((event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x01) == 0x01): dst_port = 1 else: dst_port = 0 actions = [] is_dst_local = event.parsed.next.dstip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.dstip.inNetwork(INIT_SUBNET, INIT_NETMASK) if is_dst_local and is_src_local and (dst_port != 0) and (not is_src_router): dst_mac = self.get_DHCP_mapping().get_mac(event.parsed.next.dstip) new_dl_src = of.ofp_action_dl_addr() new_dl_src.type = of.OFPAT_SET_DL_SRC # @UndefinedVariable new_dl_src.set_src(self.bridge_mac) actions.append(new_dl_src) new_dl_dst = of.ofp_action_dl_addr() new_dl_dst.type = of.OFPAT_SET_DL_DST # @UndefinedVariable new_dl_dst.set_dst(dst_mac) actions.append(new_dl_dst) out = of.ofp_action_output(port=of.OFPP_FLOOD) # @UndefinedVariable actions.append(out) if 0 < event.ofp.in_port and event.ofp.in_port < of.OFPP_MAX: # @UndefinedVariable out_of_in = of.ofp_action_output(port=of.OFPP_IN_PORT) # @UndefinedVariable actions.append(out_of_in) command = of.OFPFC_ADD # @UndefinedVariable self.send_flow_modification(event, command, actions, timeout=30)
def _modify_flow(self,command_type): msg = of.ofp_flow_mod() print self.payload if command_type == "MOD_ST": msg.command = of.OFPFC_MODIFY_STRICT elif command_type == "MOD": msg.command = of.OFPFC_MODIFY if self.payload.has_key("wildcards"): msg.match.wildcards = int(self.payload['wildcards']) if self.payload.has_key("dstIP"): msg.match.nw_dst = IPAddr(self.payload['dstIP']) if self.payload.has_key("srcMac"): msg.match.dl_src = EthAddr(self.payload['srcMac']) if self.payload.has_key("srcIP"): msg.match.nw_src = IPAddr(self.payload['srcIP']) if self.payload.has_key("dstMac"): msg.match.dl_dst = EthAddr(self.payload['dstMac']) if self.payload.has_key("hardTimeout"): msg.hard_timeout = int(self.payload['hardTimeout']) if self.payload.has_key("srcPort"): msg.match.tp_src = int(self.payload['srcPort']) if self.payload.has_key("priority"): msg.priority = int(self.payload['priority']) if self.payload.has_key("ingressPort"): msg.match.in_port = int(self.payload['ingressPort']) if self.payload.has_key("vlan"): msg.match.dl_vlan = int(self.payload['vlan']) if self.payload.has_key("ether-type"): msg.match.dl_type = int(self.payload['ether-type']) if self.payload.has_key("duration"): msg.duration_sec = int(self.payload['duration']) if self.payload.has_key("idleTimeout"): msg.idle_timeout = int(self.payload['idleTimeout']) if self.payload.has_key("netProtocol"): msg.match.nw_proto = int(self.payload['netProtocol']) self.dpid = self.payload['switch'].replace(':','-')[6:] self._parse_actions(self.payload['actions']) for connection in core.openflow._connections.values() : # print dpidToStr(connection.dpid) conn_dpid = str(dpidToStr(connection.dpid)) print conn_dpid if conn_dpid == self.dpid: """match actions""" if(self.actions == "OUTPUT"): msg.actions.append(of.ofp_action_output(port = int(self.actions_argu))) elif(self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id))) elif(self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif(self.actions == "set-vlan-id"): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu))) elif(self.actions == "set-vlan-priority"): msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu))) elif(self.actions == "SET_DL_SRC"): msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_DL_DST"): msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_NW_TOS"): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu))) elif(self.actions == "SET_NW_SRC"): msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_NW_DST"): msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_TP_SRC"): msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu))) elif(self.actions == "SET_TP_DST"): msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu))) connection.send(msg)
def _handle_PacketIn(self, event): """ Handle packet in messages from the switch to implement above algorithm. """#52:54:00:79:95:26 26:6a:fb:3c:f8:fd cptv = server_infos(conf.captive_portal.ip, conf.captive_portal.mac, conf.captive_portal.switch_port, conf.captive_portal.tcp_port ) #"130.192.225.168","52:54:00:79:95:26",5,8085) #cptv = server_infos("130.192.225.156","88:51:fb:42:2b:f8",5,8080) if self.connection.dpid not in switchs_info: lock.acquire() try: dpi = DPI() dpi.setDPI(self.connection.dpid) # add a new switch to our infos switchs_info[self.connection.dpid] = switch_infos( self.connection) finally: lock.release() # release lock, no matter what switch = switchs_info[self.connection.dpid] if event.port not in switch.ports_info: lock.acquire() try: #print (dpid_to_str(self.connection.dpid)) #print self.connection.sock.getpeername()[0] switch.ports_info[event.port] = port_infos(event.port) finally: lock.release() # release lock, no matter what #if event.port == conf.my_infos.my_default_GRE_tunnel: is_user_port = True log.info("Comparing the ports speaking " + str(event.port)) for not_user_port in conf.my_infos.not_user_ports: if str(event.port) == str(not_user_port): is_user_port = False break if not is_user_port: log.info("Event port is " + str(event.port)) log.info("First for the ethernet interface") # First rule: allow all traffic self.connection.send( of.ofp_flow_mod( action=of.ofp_action_output(port=of.OFPP_NORMAL), priority=1, match=of.ofp_match(in_port=event.port))) else: """ Packet from user """ log.info("First packet from user") # First rule: drop all traffic msg = of.ofp_flow_mod() msg.priority = 1 msg.match.in_port = event.port msg.actions.append(of.ofp_action_output(port=of.OFPP_NONE)) self.connection.send(msg) # Second rule: normal process for DNS traffic msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 17 msg.match.tp_dst = 53 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Third rule: normal process for ARP traffic msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x806 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Fourth rule: normal process for DHCPDISCOVER msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 17 msg.match.nw_src = "0.0.0.0" msg.match.nw_dst = "255.255.255.255" msg.match.tp_src = 68 msg.match.tp_dst = 67 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Fifth rule: send the HTTP traffic to the controller msg = of.ofp_flow_mod() msg.priority = 1000 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 6 msg.match.tp_dst = 80 msg.actions.append( of.ofp_action_output(port=of.OFPP_CONTROLLER)) msg.data = event.ofp self.connection.send(msg) packet = event.parsed if not packet.parsed: log.info("ignoring unparsed packet") return client_list = switch.ports_info[event.port].clients_info log.info("LOOP Thread id: " + str(thread.get_ident())) log.debug("packet.type: " + str(packet.type) + " || pkt.ethernet.IP_TYPE: " + str(pkt.ethernet.IP_TYPE)) if packet.type == pkt.ethernet.IP_TYPE: ipv4_hdr = packet.payload log.debug("ipv4_hdr.protocol: " + str(ipv4_hdr.protocol) + " || pkt.ipv4.TCP_PROTOCOL: " + str(pkt.ipv4.TCP_PROTOCOL)) if ipv4_hdr.protocol == pkt.ipv4.TCP_PROTOCOL: tcp_hdr = ipv4_hdr.payload log.info("tcp_hdr.dstport: " + str(tcp_hdr.dstport) + " || DestPort: || 80") if tcp_hdr.dstport == 80: log.debug("packet.src: " + str(packet.src)) if packet.src not in client_list: log.info("packet.src is not in client_list") lock.acquire() try: log.info("save host info: IP=" + str(ipv4_hdr.srcip) + ", MAC=" + str(packet.src) + ", INGRESS_SWITCH_PORT=" + str(switch.infos.ports[event.port].name)) client_list[packet.src] = host_infos( ipv4_hdr.srcip, packet.src, event.port, 0) finally: lock.release() # release lock, no matter what else: log.debug("PACKET_IN INFOs: user MAC: " + str(packet.src) + ", user IP: " + str(ipv4_hdr.srcip)) user_infos = client_list[packet.src] user_ip = user_infos.IP log.debug("Local informations: user MAC: " + str(packet.src) + ", user IP: " + str(user_ip)) if user_ip != ipv4_hdr.srcip: log.debug("Updating client IP informations") user_infos.IP = ipv4_hdr.srcip client = client_list[packet.src] if (client.flag_auth == 0): log.info( "installing new flow to set destination IP to captive portal IP" ) msg = of.ofp_flow_mod() msg.priority = 10000 msg.idle_timeout = 30 msg.match.dl_type = 0x800 msg.match.dl_src = client.MAC msg.match.nw_proto = 6 #Adding the match on the TCP source port of the user, in order to genererate a PACKET_IN for every #new TCP connection msg.match.tp_src = tcp_hdr.srcport msg.match.tp_dst = 80 msg.match.nw_dst = ipv4_hdr.dstip msg.match.in_port = event.port msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, cptv.MAC)) msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, cptv.IP)) msg.actions.append( of.ofp_action_tp_port(of.OFPAT_SET_TP_DST, cptv.port)) msg.actions.append( of.ofp_action_output(port=cptv.switch_port)) #msg.data = event.ofp self.connection.send(msg) log.info("installing new flow to set return path") msg = of.ofp_flow_mod() msg.priority = 10000 msg.idle_timeout = 30 msg.match.dl_type = 0x800 msg.match.nw_proto = 6 msg.match.tp_dst = tcp_hdr.srcport msg.match.nw_dst = ipv4_hdr.srcip msg.match.nw_src = cptv.IP msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, ipv4_hdr.dstip)) msg.actions.append( of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC, tcp_hdr.dstport)) msg.actions.append( of.ofp_action_output(port=event.port)) msg.data = event.ofp self.connection.send(msg) '''
def _modify_flow(self, command_type): msg = of.ofp_flow_mod() print self.payload if command_type == "MOD_ST": msg.command = of.OFPFC_MODIFY_STRICT elif command_type == "MOD": msg.command = of.OFPFC_MODIFY if self.payload.has_key("wildcards"): msg.match.wildcards = int(self.payload['wildcards']) if self.payload.has_key("dstIP"): msg.match.nw_dst = IPAddr(self.payload['dstIP']) if self.payload.has_key("srcMac"): msg.match.dl_src = EthAddr(self.payload['srcMac']) if self.payload.has_key("srcIP"): msg.match.nw_src = IPAddr(self.payload['srcIP']) if self.payload.has_key("dstMac"): msg.match.dl_dst = EthAddr(self.payload['dstMac']) if self.payload.has_key("hardTimeout"): msg.hard_timeout = int(self.payload['hardTimeout']) if self.payload.has_key("srcPort"): msg.match.tp_src = int(self.payload['srcPort']) if self.payload.has_key("priority"): msg.priority = int(self.payload['priority']) if self.payload.has_key("ingressPort"): msg.match.in_port = int(self.payload['ingressPort']) if self.payload.has_key("vlan"): msg.match.dl_vlan = int(self.payload['vlan']) if self.payload.has_key("ether-type"): msg.match.dl_type = int(self.payload['ether-type']) if self.payload.has_key("duration"): msg.duration_sec = int(self.payload['duration']) if self.payload.has_key("idleTimeout"): msg.idle_timeout = int(self.payload['idleTimeout']) if self.payload.has_key("netProtocol"): msg.match.nw_proto = int(self.payload['netProtocol']) self.dpid = self.payload['switch'].replace(':', '-')[6:] self._parse_actions(self.payload['actions']) for connection in core.openflow._connections.values(): # print dpidToStr(connection.dpid) conn_dpid = str(dpidToStr(connection.dpid)) print conn_dpid if conn_dpid == self.dpid: """match actions""" if (self.actions == "OUTPUT"): msg.actions.append( of.ofp_action_output(port=int(self.actions_argu))) elif (self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append( of.ofp_action_enqueue(port=int(port), queue_id=int(queue_id))) elif (self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif (self.actions == "set-vlan-id"): msg.actions.append( of.ofp_action_vlan_vid( vlan_vid=int(self.actions_argu))) elif (self.actions == "set-vlan-priority"): msg.actions.append( of.ofp_action_vlan_pcp( vlan_pcp=int(self.actions_argu))) elif (self.actions == "SET_DL_SRC"): msg.actions.append( of.ofp_action_dl_addr(type=4, dl_addr=EthAddr( self.actions_argu))) elif (self.actions == "SET_DL_DST"): msg.actions.append( of.ofp_action_dl_addr(type=5, dl_addr=EthAddr( self.actions_argu))) elif (self.actions == "SET_NW_TOS"): msg.actions.append( of.ofp_action_nw_tos(nw_tos=int(self.actions_argu))) elif (self.actions == "SET_NW_SRC"): msg.actions.append( of.ofp_action_nw_addr(type=6, nw_addr=IPAddr( self.actions_argu))) elif (self.actions == "SET_NW_DST"): msg.actions.append( of.ofp_action_nw_addr(type=7, nw_addr=IPAddr( self.actions_argu))) elif (self.actions == "SET_TP_SRC"): msg.actions.append( of.ofp_action_tp_port(type=9, tp_port=int(self.actions_argu))) elif (self.actions == "SET_TP_DST"): msg.actions.append( of.ofp_action_tp_port(type=10, tp_port=int(self.actions_argu))) connection.send(msg)
def _handle_PacketIn(self, event): balancer_ip = IPAddr("10.0.0.99") balancer_eth = EthAddr("00:00:00:00:00:99") packet = event.parsed packet_in = event.ofp flow = of.ofp_flow_mod() flow.match = of.ofp_match.from_packet(packet) flow.match.in_port = packet_in.in_port if flow.match.nw_src not in self.dicts: self.dicts[flow.match.nw_src] = packet_in.in_port if flow.match.nw_dst == balancer_ip: # if the request is to balancer print("[Request]: From " + str(flow.match.nw_src) + " to " + str(flow.match.nw_dst)) if flow.match.in_port == self.ind + 1: # if the chosen server is the same as the client self.ind = (self.ind + 1) % self.N # shift the server id ethnum = str(hex(self.ind + 1)) if self.ind < 15: ethnum = "0" + ethnum[2:len(ethnum)] else: ethnum = ethnum[2:len(ethnum)] ipnum = str(self.ind + 1) server_port = self.ind + 1 server_ip = IPAddr("10.0.0." + ipnum) server_eth = EthAddr("00:00:00:00:00:" + ethnum) print("The chosen server is " + str(server_ip)) print(server_eth) flow.buffer_id = packet_in.buffer_id new_ip_dst = of.ofp_action_nw_addr(7, server_ip) new_eth_dst = of.ofp_action_dl_addr(5, server_eth) action = of.ofp_action_output(port=server_port) flow.actions.append(new_ip_dst) flow.actions.append(new_eth_dst) self.ind = (self.ind + 1) % self.N flow.idle_timeout = of.OFP_FLOW_PERMANENT flow.hard_timeout = of.OFP_FLOW_PERMANENT flow.priority = 65535 flow.actions.append(action) event.connection.send(flow) flow.command = of.OFPFC_DELETE event.connection.send(flow) # indicate the current server and client info self.cur_client = packet_in.in_port self.cur_ser = server_port self.request = 1 else: if flow.match.nw_dst in self.dicts: outport = self.dicts[flow.match.nw_dst] else: outport = of.OFPP_ALL if outport == self.cur_client and self.request == 1: #response message new_ip_src = of.ofp_action_nw_addr(6, balancer_ip) new_eth_src = of.ofp_action_dl_addr(4, balancer_eth) action = of.ofp_action_output(port=outport) flow.buffer_id = packet_in.buffer_id flow.idle_timeout = of.OFP_FLOW_PERMANENT flow.hard_timeout = of.OFP_FLOW_PERMANENT flow.priority = 65535 flow.actions.append(new_ip_src) flow.actions.append(new_eth_src) flow.actions.append(action) event.connection.send(flow) flow.command = of.OFPFC_DELETE event.connection.send(flow) print("[Response]: Server " + str(self.cur_ser) + " response") self.cur_ser = -1 self.cur_client = -1 self.request = 0 else: action = of.ofp_action_output(port=outport) flow.idle_timeout = of.OFP_FLOW_PERMANENT flow.hard_timeout = of.OFP_FLOW_PERMANENT flow.priority = 65535 flow.actions.append(action) if event.ofp.buffer_id != -1: flow.buffer_id = event.ofp.buffer_id event.connection.send(flow) print("Normal Message from " + str(flow.match.nw_src) + " to " + str(flow.match.nw_dst)) flow.command = of.OFPFC_DELETE event.connection.send(flow) return
def _handle_PacketIn (self, event): """ Handle packet in messages from the switch to implement above algorithm. """#52:54:00:79:95:26 26:6a:fb:3c:f8:fd cptv = server_infos(conf.captive_portal.ip,conf.captive_portal.mac,conf.captive_portal.switch_port,conf.captive_portal.tcp_port)#"130.192.225.168","52:54:00:79:95:26",5,8085) #cptv = server_infos("130.192.225.156","88:51:fb:42:2b:f8",5,8080) if self.connection.dpid not in switchs_info: lock.acquire() try: dpi = DPI() dpi.setDPI(self.connection.dpid) # add a new switch to our infos switchs_info[self.connection.dpid] = switch_infos(self.connection) finally: lock.release() # release lock, no matter what switch = switchs_info[self.connection.dpid] if event.port not in switch.ports_info: lock.acquire() try: #print (dpid_to_str(self.connection.dpid)) #print self.connection.sock.getpeername()[0] switch.ports_info[event.port] = port_infos(event.port) finally: lock.release() # release lock, no matter what #if event.port == conf.my_infos.my_default_GRE_tunnel: is_user_port = True log.info("Comparing the ports speaking " + str(event.port)) for not_user_port in conf.my_infos.not_user_ports: if str(event.port) == str(not_user_port): is_user_port = False break if not is_user_port: log.info("Event port is " + str(event.port)) log.info("First for the ethernet interface") # First rule: allow all traffic self.connection.send( of.ofp_flow_mod( action=of.ofp_action_output(port=of.OFPP_NORMAL), priority=1, match=of.ofp_match( in_port = event.port))) else: """ Packet from user """ log.info("First packet from user") # First rule: drop all traffic msg = of.ofp_flow_mod() msg.priority = 1 msg.match.in_port = event.port msg.actions.append(of.ofp_action_output(port=of.OFPP_NONE)) self.connection.send(msg) # Second rule: normal process for DNS traffic msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 17 msg.match.tp_dst = 53 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Third rule: normal process for ARP traffic msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x806 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Fourth rule: normal process for DHCPDISCOVER msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 17 msg.match.nw_src = "0.0.0.0" msg.match.nw_dst = "255.255.255.255" msg.match.tp_src = 68 msg.match.tp_dst = 67 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Fifth rule: send the HTTP traffic to the controller msg = of.ofp_flow_mod() msg.priority = 1000 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 6 msg.match.tp_dst = 80 msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) msg.data = event.ofp self.connection.send(msg) packet = event.parsed if not packet.parsed: log.info("ignoring unparsed packet") return client_list = switch.ports_info[event.port].clients_info log.info("LOOP Thread id: "+str(thread.get_ident() )) log.debug("packet.type: "+ str(packet.type) +" || pkt.ethernet.IP_TYPE: "+ str(pkt.ethernet.IP_TYPE)) if packet.type == pkt.ethernet.IP_TYPE: ipv4_hdr = packet.payload log.debug("ipv4_hdr.protocol: "+ str(ipv4_hdr.protocol) +" || pkt.ipv4.TCP_PROTOCOL: "+ str(pkt.ipv4.TCP_PROTOCOL)) if ipv4_hdr.protocol == pkt.ipv4.TCP_PROTOCOL: tcp_hdr = ipv4_hdr.payload log.info("tcp_hdr.dstport: "+ str(tcp_hdr.dstport) +" || DestPort: || 80") if tcp_hdr.dstport == 80: log.debug("packet.src: "+ str(packet.src)) if str(packet.src) not in client_list: log.info("packet.src is not in client_list") lock.acquire() try: log.info("save host info: IP=" + str(ipv4_hdr.srcip) + ", MAC=" + str(packet.src) + ", INGRESS_SWITCH_PORT=" + str(switch.infos.ports[event.port].name)) client_list[str(packet.src)] = host_infos(ipv4_hdr.srcip,packet.src,event.port,0) finally: lock.release() # release lock, no matter what else: log.debug("PACKET_IN INFOs: user MAC: "+ str(packet.src)+", user IP: "+ str(ipv4_hdr.srcip)) user_infos = client_list[str(packet.src)] user_ip = user_infos.IP log.debug("Local informations: user MAC: "+ str(packet.src)+", user IP: "+ str(user_ip)) if user_ip != ipv4_hdr.srcip: log.debug("Updating client IP informations") user_infos.IP = ipv4_hdr.srcip client = client_list[str(packet.src)] if (client.flag_auth == 0): log.info("installing new flow to set destination IP to captive portal IP") msg = of.ofp_flow_mod() msg.priority = 10000 msg.idle_timeout=30 msg.match.dl_type = 0x800 msg.match.dl_src = client.MAC msg.match.nw_proto = 6 #Adding the match on the TCP source port of the user, in order to genererate a PACKET_IN for every #new TCP connection msg.match.tp_src = tcp_hdr.srcport msg.match.tp_dst = 80 msg.match.nw_dst = ipv4_hdr.dstip msg.match.in_port = event.port msg.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST,cptv.MAC)) msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST,cptv.IP)) msg.actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_DST,cptv.port)) msg.actions.append(of.ofp_action_output(port=cptv.switch_port)) #msg.data = event.ofp self.connection.send(msg) log.info("installing new flow to set return path") msg = of.ofp_flow_mod() msg.priority = 10000 msg.idle_timeout=30 msg.match.dl_type = 0x800 msg.match.nw_proto = 6 msg.match.tp_dst = tcp_hdr.srcport msg.match.nw_dst = ipv4_hdr.srcip msg.match.nw_src = cptv.IP msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC,ipv4_hdr.dstip)) msg.actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC,tcp_hdr.dstport)) msg.actions.append(of.ofp_action_output(port=event.port)) msg.data = event.ofp self.connection.send(msg) '''
def packet_handler(event): global count_server packet = event.parsed # Only handle IPv4 flows if (not event.parsed.find("ipv4")): return event_cont message = of.ofp_flow_mod() message.match = of.ofp_match.from_packet(packet) # Handing requests routed to the Load Balancer Ip if (message.match.nw_dst != virtual_ip): return event_cont # Implemented Weighted Random Server Selection iterator = server_no % 6 print iterator if (IPAddr(message.match.nw_src) in clients): iterator = clients[IPAddr(message.match.nw_src)] serverip = topology_server[iterator]['ip'] selected_server_mac = topology_server[iterator]['mac'] server_output = topology_server[iterator]['outport'] elif (iterator < topology_server[0]['weight']): serverip = topology_server[0]['ip'] selected_server_mac = topology_server[0]['mac'] server_output = topology_server[0]['outport'] clients[IPAddr(message.match.nw_src)] = 0 server_no += 1 elif (iterator < (topology_server[0]['weight'] + topology_server[1]['weight'])): serverip = topology_server[1]['ip'] selected_server_mac = topology_server[1]['mac'] server_output = topology_server[1]['outport'] clients[IPAddr(message.match.nw_src)] = 1 server_no += 1 elif (iterator < (topology_server[0]['weight'] + topology_server[1]['weight'] + topology_server[2]['weight'])): serverip = topology_server[2]['ip'] selected_server_mac = topology_server[2]['mac'] server_output = topology_server[2]['outport'] clients[IPAddr(message.match.nw_src)] = 2 server_no += 1 # Route followed to server message.buffer_id = event.ofp.buffer_id message.in_port = event.port message.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) message.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, serverip)) message.actions.append(of.ofp_action_output(port=server_output)) event.connection.send(message) # Route from server to load balancer reply = of.ofp_flow_mod() reply.buffer_id = None reply.in_port = server_output reply.match = of.ofp_match() reply.match.dl_src = selected_server_mac reply.match.nw_src = serverip reply.match.tp_src = message.match.tp_dst reply.match.dl_dst = message.match.dl_src reply.match.nw_dst = message.match.nw_src reply.match.tp_dst = message.match.tp_src reply.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac)) reply.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, virtual_ip)) reply.actions.append(of.ofp_action_output(port=message.in_port)) event.connection.send(reply) return EventHalt
def genRule(self, hop, nexthop, source, destination, first=False, last=False, cookie=0x0c): """generate a list of openflow rules first: hop is the first hop last: nexthop is the last hop returngateway: hop is a gateway on the return path """ #DEFAULT_HARD_TIMEOUT = of.OFP_FLOW_PERMANENT #DEFAULT_HARD_TIMEOUT = 0 #DEFAULT_IDLE_TIMEOUT = of.OFP_FLOW_PERMANENT DEFAULT_IDLE_TIMEOUT = 60 if not self.isSwitch(hop): return [] orules = [] try: if first: orule = of.ofp_flow_mod( command = of.OFPFC_ADD, priority = self.priority, idle_timeout = DEFAULT_IDLE_TIMEOUT, #hard_timeout = DEFAULT_HARD_TIMEOUT, #flags= of.OFPFF_CHECK_OVERLAP, cookie = cookie, match = of.ofp_match( dl_type = 0x800, nw_src = IPAddr(source), nw_dst = IPAddr(destination), #dl_dst = of.EthAddr(self.ip2mac(nexthop)), in_port = of.OFPP_LOCAL ), ) oactions = [of.ofp_action_dl_addr(type = of.OFPAT_SET_DL_DST, dl_addr = self.ip2mac(nexthop)), of.ofp_action_dl_addr(type = of.OFPAT_SET_DL_SRC, dl_addr = self.ip2mac(hop)), of.ofp_action_output(port = of.OFPP_ALL)] orule.actions = oactions orule.switchip = hop orules.append(orule) elif last or self.isGateWay(hop): localport = self.getPortInfo(self.ip2switchId(hop), of.OFPP_LOCAL) orule = of.ofp_flow_mod( command = of.OFPFC_ADD, priority = self.priority, idle_timeout = DEFAULT_IDLE_TIMEOUT, #hard_timeout = DEFAULT_HARD_TIMEOUT, #flags= of.OFPFF_CHECK_OVERLAP, cookie = cookie, match = of.ofp_match( dl_type = 0x800, nw_src = IPAddr(source), nw_dst = IPAddr(destination), # matching all the switch MAC addresses here would be better ), ) oactions = [] try: oactions.append(of.ofp_action_dl_addr(type = of.OFPAT_SET_DL_DST, dl_addr = localport['hw_addr'])) except TypeError: pass oactions.append(of.ofp_action_output(port = of.OFPP_LOCAL)) orule.actions = oactions orule.switchip = hop orules.append(orule) else: # Needed for HNAs orule = of.ofp_flow_mod( command = of.OFPFC_ADD, priority = self.priority, idle_timeout = DEFAULT_IDLE_TIMEOUT, #hard_timeout = DEFAULT_HARD_TIMEOUT, #flags= of.OFPFF_CHECK_OVERLAP, cookie = cookie, match = of.ofp_match( dl_type = 0x800, nw_src = IPAddr(source), nw_dst = IPAddr(destination), in_port = of.OFPP_LOCAL ), ) oactions = [] try: oactions.append(of.ofp_action_dl_addr(type = of.OFPAT_SET_DL_DST, dl_addr = self.ip2mac(nexthop))) oactions.append(of.ofp_action_dl_addr(type = of.OFPAT_SET_DL_SRC, dl_addr = self.ip2mac(hop))) wirelessport = self.getPortInfo(self.ip2switchId(hop), "eth0") #TODO: parametrize if wirelessport != None and wirelessport.has_key('port_no'): oactions.append(of.ofp_action_output(port = wirelessport['port_no'])) orule.actions = oactions orule.switchip = hop orules.append(orule) else: self.log.warn("No wireless port info for %s?" % hop) except Exception, e: self.log.warn("HNA rule problem (%s -> %s): %s" % (hop, nexthop, e)) self.priority += 1 # intermediate node orule = of.ofp_flow_mod( command = of.OFPFC_ADD, priority = self.priority, idle_timeout = DEFAULT_IDLE_TIMEOUT, #hard_timeout = DEFAULT_HARD_TIMEOUT, #flags= of.OFPFF_CHECK_OVERLAP, cookie = cookie, match = of.ofp_match( dl_type = 0x800, nw_src = IPAddr(source), nw_dst = IPAddr(destination), dl_dst = of.EthAddr(self.ip2mac(hop)) ), ) oactions = [of.ofp_action_dl_addr(type = of.OFPAT_SET_DL_DST, dl_addr = self.ip2mac(nexthop)), of.ofp_action_dl_addr(type = of.OFPAT_SET_DL_SRC, dl_addr = self.ip2mac(hop)), of.ofp_action_output(port = of.OFPP_IN_PORT)] orule.actions = oactions orule.switchip = hop orules.append(orule) self.priority += 1 if self.priority>11000 : self.priority=10000
def genRule(self, hop, nexthop, source, destination, first=False, last=False, cookie=0x0c): """generate a list of openflow rules first: hop is the first hop last: nexthop is the last hop returngateway: hop is a gateway on the return path """ #DEFAULT_HARD_TIMEOUT = of.OFP_FLOW_PERMANENT #DEFAULT_HARD_TIMEOUT = 0 #DEFAULT_IDLE_TIMEOUT = of.OFP_FLOW_PERMANENT DEFAULT_IDLE_TIMEOUT = 60 if not self.isSwitch(hop): return [] orules = [] try: if first: orule = of.ofp_flow_mod( command=of.OFPFC_ADD, priority=self.priority, idle_timeout=DEFAULT_IDLE_TIMEOUT, #hard_timeout = DEFAULT_HARD_TIMEOUT, #flags= of.OFPFF_CHECK_OVERLAP, cookie=cookie, match=of.ofp_match( dl_type=0x800, nw_src=IPAddr(source), nw_dst=IPAddr(destination), #dl_dst = of.EthAddr(self.ip2mac(nexthop)), in_port=of.OFPP_LOCAL), ) oactions = [ of.ofp_action_dl_addr(type=of.OFPAT_SET_DL_DST, dl_addr=self.ip2mac(nexthop)), of.ofp_action_dl_addr(type=of.OFPAT_SET_DL_SRC, dl_addr=self.ip2mac(hop)), of.ofp_action_output(port=of.OFPP_ALL) ] orule.actions = oactions orule.switchip = hop orules.append(orule) elif last or self.isGateWay(hop): localport = self.getPortInfo(self.ip2switchId(hop), of.OFPP_LOCAL) orule = of.ofp_flow_mod( command=of.OFPFC_ADD, priority=self.priority, idle_timeout=DEFAULT_IDLE_TIMEOUT, #hard_timeout = DEFAULT_HARD_TIMEOUT, #flags= of.OFPFF_CHECK_OVERLAP, cookie=cookie, match=of.ofp_match( dl_type=0x800, nw_src=IPAddr(source), nw_dst=IPAddr(destination), # matching all the switch MAC addresses here would be better ), ) oactions = [] try: oactions.append( of.ofp_action_dl_addr(type=of.OFPAT_SET_DL_DST, dl_addr=localport['hw_addr'])) except TypeError: pass oactions.append(of.ofp_action_output(port=of.OFPP_LOCAL)) orule.actions = oactions orule.switchip = hop orules.append(orule) else: # Needed for HNAs orule = of.ofp_flow_mod( command=of.OFPFC_ADD, priority=self.priority, idle_timeout=DEFAULT_IDLE_TIMEOUT, #hard_timeout = DEFAULT_HARD_TIMEOUT, #flags= of.OFPFF_CHECK_OVERLAP, cookie=cookie, match=of.ofp_match(dl_type=0x800, nw_src=IPAddr(source), nw_dst=IPAddr(destination), in_port=of.OFPP_LOCAL), ) oactions = [] try: oactions.append( of.ofp_action_dl_addr(type=of.OFPAT_SET_DL_DST, dl_addr=self.ip2mac(nexthop))) oactions.append( of.ofp_action_dl_addr(type=of.OFPAT_SET_DL_SRC, dl_addr=self.ip2mac(hop))) wirelessport = self.getPortInfo(self.ip2switchId(hop), "eth0") #TODO: parametrize if wirelessport != None and wirelessport.has_key( 'port_no'): oactions.append( of.ofp_action_output(port=wirelessport['port_no'])) orule.actions = oactions orule.switchip = hop orules.append(orule) else: self.log.warn("No wireless port info for %s?" % hop) except Exception, e: self.log.warn("HNA rule problem (%s -> %s): %s" % (hop, nexthop, e)) self.priority += 1 # intermediate node orule = of.ofp_flow_mod( command=of.OFPFC_ADD, priority=self.priority, idle_timeout=DEFAULT_IDLE_TIMEOUT, #hard_timeout = DEFAULT_HARD_TIMEOUT, #flags= of.OFPFF_CHECK_OVERLAP, cookie=cookie, match=of.ofp_match(dl_type=0x800, nw_src=IPAddr(source), nw_dst=IPAddr(destination), dl_dst=of.EthAddr(self.ip2mac(hop))), ) oactions = [ of.ofp_action_dl_addr(type=of.OFPAT_SET_DL_DST, dl_addr=self.ip2mac(nexthop)), of.ofp_action_dl_addr(type=of.OFPAT_SET_DL_SRC, dl_addr=self.ip2mac(hop)), of.ofp_action_output(port=of.OFPP_IN_PORT) ] orule.actions = oactions orule.switchip = hop orules.append(orule) self.priority += 1 if self.priority > 11000: self.priority = 10000
def _handle_PacketIn(self, event): # parsing the input packet packet = event.parse() # If no switch has ever seen this host before, then it must be directly # connected to us! Record that in our global list. if packet.src not in self.hostlocations or self.hostlocations[ packet.src]["lastseen"] < (datetime.now() - timedelta(0, IDLE_TIMEOUT)): #log.debug("s%s takes ownership of host %s" % (self.connection.ID, packet.src)) self.hostlocations[packet.src] = { "ID": self.connection.ID, "lastseen": datetime.now() } # Record which hosts exists on which of our ports ip = GetIPFromMAC(packet.src) if ip is not None: #log.debug(" on IP '%s'" % ip) self.hostports[event.port] = packet.src elif self.hostlocations[packet.src]["ID"] == self.connection.ID: #log.debug("s%s continues to own host %s" % (datetime.now(), self.connection.ID, packet.src)) self.hostlocations[packet.src]["lastseen"] = datetime.now() # Keep a list of which MAC addresses live on which port, so we can forward # packets as needed if packet.src not in self.mactable or self.mactable[ packet.src] != event.ofp.in_port: self.mactable[packet.src] = event.ofp.in_port #log.debug("Learned port %s connects to %s" % (event.ofp.in_port, packet.src)) if packet.type == packet.LLDP_TYPE or packet.type == 0x86DD: # Drop LLDP packets # Drop IPv6 packets # send of command without actions msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) return # Watch for ARP packets trying to discover a load-balance target. packet_arp = packet.find('arp') if packet_arp is not None and str( packet_arp.protodst).startswith(LOADBALANCE_TARGET): # Found one! Respond with a special MAC address, which our switches will # be able to identify easily for load-balancing. #log.debug('ARP Packet!!!! Looking for %s' % packet_arp.protodst) mac = GetMACForLoadBalancing() reply_arp = arp() reply_arp.hwtype = packet_arp.hwtype reply_arp.prototype = packet_arp.prototype reply_arp.hwlen = packet_arp.hwlen reply_arp.protolen = packet_arp.protolen reply_arp.opcode = arp.REPLY reply_arp.hwdst = packet_arp.hwsrc reply_arp.hwsrc = mac reply_arp.protodst = packet_arp.protosrc reply_arp.protosrc = packet_arp.protodst reply_eth = ethernet(type=packet.type, src=mac, dst=packet_arp.hwsrc) reply_eth.payload = reply_arp reply = of.ofp_packet_out(in_port=of.OFPP_NONE) reply.actions.append(of.ofp_action_output(port=event.port)) reply.data = reply_eth.pack() event.connection.send(reply) return # If this packet is being delivered to a special MAC, set up some flows to # get the data to the right place. packet_ipv4 = packet.find('ipv4') if IsMACForLoadBalancing(packet.dst) and packet_ipv4 is not None: eligibleports = [] for port in self.connection.features.ports: if port.port_no != event.port and not port.config & OFPPC_PORT_DOWN: eligibleports.append(port.port_no) port_out = random.choice(eligibleports) # Establish bi-directional flows! log.debug("Establishing load-balancing flows for %s <--> %s" % (packet.src, packet.dst)) flow_in = of.ofp_flow_mod() flow_out = of.ofp_flow_mod() flow_in.idle_timeout = flow_out.idle_timeout = IDLE_TIMEOUT flow_in.hard_timeout = flow_out.hard_timeout = HARD_TIMEOUT flow_in.match = of.ofp_match(dl_dst=packet.src, dl_src=packet.dst) flow_out.match = of.ofp_match(dl_dst=packet.dst, dl_src=packet.src) if port_out in self.hostports: # If we're delivering to a host (instead of another switch), we need # to rewrite some of the packet data, so that things line up properly # on each end. The sender sends to the special IP, and the receiver # should see the packet addressed to itself (and vice versa). log.debug("...which will be handled by %s" % (self.hostports[port_out])) flow_in.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, packet.dst)) flow_in.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, packet_ipv4.dstip)) flow_out.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, self.hostports[port_out])) flow_out.actions.append( of.ofp_action_nw_addr( of.OFPAT_SET_NW_DST, GetIPFromMAC(self.hostports[port_out]))) # We also need to update one of our match rules, since the packet will # be sent with a non-special MAC address. flow_in.match.dl_src = self.hostports[port_out] flow_in.actions.append(of.ofp_action_output(port=event.port)) flow_out.actions.append(of.ofp_action_output(port=port_out)) flow_in.in_port = port_out flow_out.in_port = event.port flow_out.data = event.ofp self.connection.send(flow_in) self.connection.send(flow_out) return elif packet.dst in self.mactable: # If we know the destination, but are being told about it, recreate the # flow, since this is either the initial discovery, or the flow expired. log.debug( "Establishing flow to deliver packets for %s to port %s" % (packet.dst, self.mactable[packet.dst])) fm = of.ofp_flow_mod() fm.idle_timeout = IDLE_TIMEOUT fm.hard_timeout = HARD_TIMEOUT fm.actions.append( of.ofp_action_output(port=self.mactable[packet.dst])) # Defining the match via from_packet will cause us to establish a flow # for each unique packet type per destination, instead of just per dest. fm.match = of.ofp_match(dl_dst=packet.dst, dl_src=packet.src) #fm.match = of.ofp_match.from_packet(packet) fm.data = event.ofp # Deliver the packet along this flow self.connection.send(fm) return log.debug("Port for %s unknown -- flooding" % (packet.dst, )) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg)