<commit_before>#!/usr/bin/python

#----------------------------------------------------------------------
# Copyright (c) 2013 <NAME>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and/or hardware specification (the "Work") to
# deal in the Work without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Work, and to permit persons to whom the Work
# is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Work.
#
# THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS
# IN THE WORK.
#----------------------------------------------------------------------

# Handle the client connection between the VMOC and 
# each registered controller for each switch

import inspect
import select
import socket
import threading
import pdb
from pox.core import core
from pox.lib.util import makePinger
from pox.lib.packet.ethernet import ethernet
from pox.lib.addresses import EthAddr
from pox.lib.packet.vlan import vlan
from pox.openflow.util import make_type_to_unpacker_table
from pox.openflow.libopenflow_01 import *
from pox.openflow import libopenflow_01 as of
from pox.lib.packet.ethernet import ethernet
from pox.lib.packet.vlan import vlan
import VMOCSwitchControllerMap as scmap
from VMOCSliceRegistry import slice_registry_lookup_slices_by_url, slice_registry_dump
from VMOCUtils import *
import gram.am.gram.config as config


log = core.getLogger() # Use central logging service

# Thread to manage connection with a controller:
# Listen to and process all messages received asynchronously from controller
class VMOCControllerConnection(threading.Thread):


    def __init__(self, url, switch_connection, vlan, open_on_create=True):
        threading.Thread.__init__(self)
        self._running = False
        self._vlan = int(vlan)

        self.ofp_msgs = make_type_to_unpacker_table()
        self.ofp_handlers = {
            # Reactive handlers
            ofp_type_rev_map['OFPT_HELLO'] : self._receive_hello,
            ofp_type_rev_map['OFPT_ECHO_REQUEST'] : self._receive_echo,
            ofp_type_rev_map['OFPT_FEATURES_REQUEST'] : \
                self._receive_features_request,
            ofp_type_rev_map['OFPT_FLOW_MOD'] : self._receive_flow_mod,
            ofp_type_rev_map['OFPT_PACKET_OUT'] : self._receive_packet_out,
            ofp_type_rev_map['OFPT_BARRIER_REQUEST'] : \
                self._receive_barrier_request,
            ofp_type_rev_map['OFPT_GET_CONFIG_REQUEST'] : \
                self._receive_get_config_request,
            ofp_type_rev_map['OFPT_SET_CONFIG'] : self._receive_set_config,
            ofp_type_rev_map['OFPT_STATS_REQUEST'] : \
                self._receive_stats_request,
            ofp_type_rev_map['OFPT_VENDOR'] : self._receive_vendor,
            # Proactive responses
            ofp_type_rev_map['OFPT_ECHO_REPLY'] : self._receive_echo_reply
            # TODO: many more packet types to process
            }


        self._switch_connection = switch_connection
        if  not hasattr(switch_connection, '_dpid'): pdb.set_trace()

        # The controller sees VMOC as a switch. And we want each
        # connection to a controller to have a different DPID (or controllers
        # get confused). So VMOC has a different connection to a controller
        # by VLAN. And a controller may connect to multiple VMOCs.
        # So we need to construct a DPID that is unique over the space
        # of VLAN and switch_DPID.
        #
        # Here's what we do.
        # DPID's are 64 bits, of which the lower 48 are MAC addresses
        # and the top 16 are 'implementer defined' (Openflow spec).
        # The MAC should be unique and (for the contoller to talk to VMOC
        # we don't need to maintain the switch implementation features.
        # The vlan is 3 hex digits or 12 bits. 
        # So we take the VLAN and put it at the top three hex bytes of
        # the switch's DPID to form the VMOC-Controller-VLAN-specific DPIC
        #
        # VLAN in top 3 hex chars
        # Switch DPID in lower 13 hex chars
        controller_connection_dpid = \
            ((self._vlan & 0xfff) << 48) + \
            (switch_connection._dpid & 0x000fffffffffffff)  
        self._dpid = controller_connection_dpid

        self._url = url
        (host, port) = VMOCControllerConnection.parseURL(url)
        self._host = host;
        self._port = port
        self._sock = None

        # Make it optional to not open on create (for debugging at least)
        if open_on_create:
            self.open()

    def open(self):
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.connect((self._host, self._port))
        self.start()
        # When we have a new controller, send it a 'hello' (acting like
        # we are a switch to whom they are talking
        hello_msg = of.ofp_hello()
        self.send(hello_msg)

    def close(self):
#        print "CLOSING " + str(self)
        self._sock.close()
#        print "SOCKET CLOSED " + str(self)
        self._running = False
#        print "RUNNING = FALSE " + str(self)

    def __str__(self):
        return "[VMOCControllerConnection DPID %s URL %s VLAN %d]" % (self._dpid, self._url, self._vlan)

    def getURL(self):
        return self._url

    def getVLAN(self):
        return self._vlan

    def getSwitchConnection(self):
        return self._switch_connection

    def _receive_hello(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_HELLO")
#        log.debug("CC " +  str(ofp))

    def _receive_echo(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_ECHO_REQUEST")
#        log.debug("CC " +  str(ofp))
        echo_reply = ofp_echo_reply(xid=ofp.xid)
        self.send(echo_reply)

    def _receive_features_request(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_FEATURES_REQUEST")
#        log.debug("CC " +  str(ofp))
        switch = scmap.lookup_switch_for_controller_connection(self)
        features_reply = switch._features_reply
#        print "Features Request " + str(ofp.xid) + " " + str(features_reply.xid)
        features_reply.xid = ofp.xid
        self.send(features_reply)

    def _receive_flow_mod(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_FLOW_MOD")
#        log.debug("CC " +  str(ofp))
        # Need to forward this back to the switch
        self.forwardToAllAppropriateSwitches(ofp)

    def _receive_packet_out(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_PACKET_OUT")
        self.forwardToAllAppropriateSwitches(ofp)
#        log.debug("CC " +  str(ofp))

    def _receive_barrier_request(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_BARRIER_REQUEST")
#        log.debug("CC " +  str(ofp))
#        print "BARRIER ID " + str(ofp.xid)
        barrier_reply = ofp_barrier_reply(xid = ofp.xid)
#        print "BARRIER_REPLY = " + str(barrier_reply)
#        print "BARRIER_REQUEST = " + str(ofp)
        self.send(barrier_reply)

    def _receive_get_config_request(self, ofp):
        log.debug("CC " + self._url + " recvd " + \
                      "'OFPT_GET_CONFIG_REQUEST" + str(ofp))
#        log.debug("CC " + self._url + " recvd " + "'OFPT_GET_CONFIG_REQUEST ")

    def _receive_set_config(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_SET_CONFIG")
#        log.debug("CC " + str(ofp))

    def _receive_stats_request(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_STATS_REQUEST")
#        log.debug("CC " +  str(ofp))

    def _receive_vendor(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_VENDOR")
#        log.debug("CC " +  str(ofp))

    def _receive_echo_reply(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_ECHO_REPLY")
#        log.debug("CC " +  str(ofp))

    # For now, forward the ofp to all switches assocaited with VMOC<commit_msg>Support config and  stats reqeusts<commit_after>#!/usr/bin/python

#----------------------------------------------------------------------
# Copyright (c) 2013 <NAME>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and/or hardware specification (the "Work") to
# deal in the Work without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Work, and to permit persons to whom the Work
# is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Work.
#
# THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS
# IN THE WORK.
#----------------------------------------------------------------------

# Handle the client connection between the VMOC and 
# each registered controller for each switch

import inspect
import select
import socket
import threading
import pdb
from pox.core import core
from pox.lib.util import makePinger
from pox.lib.packet.ethernet import ethernet
from pox.lib.addresses import EthAddr
from pox.lib.packet.vlan import vlan
from pox.openflow.util import make_type_to_unpacker_table
from pox.openflow.libopenflow_01 import *
from pox.openflow import libopenflow_01 as of
from pox.lib.packet.ethernet import ethernet
from pox.lib.packet.vlan import vlan
import VMOCSwitchControllerMap as scmap
from VMOCSliceRegistry import slice_registry_lookup_slices_by_url, slice_registry_dump
from VMOCUtils import *
import gram.am.gram.config as config

log = core.getLogger() # Use central logging service

# Thread to manage connection with a controller:
# Listen to and process all messages received asynchronously from controller
class VMOCControllerConnection(threading.Thread):


    def __init__(self, url, switch_connection, vlan, open_on_create=True):
        threading.Thread.__init__(self)
        self._running = False
        self._vlan = int(vlan)

        self.ofp_msgs = make_type_to_unpacker_table()
        self.ofp_handlers = {
            # Reactive handlers
            ofp_type_rev_map['OFPT_HELLO'] : self._receive_hello,
            ofp_type_rev_map['OFPT_ECHO_REQUEST'] : self._receive_echo,
            ofp_type_rev_map['OFPT_FEATURES_REQUEST'] : \
                self._receive_features_request,
            ofp_type_rev_map['OFPT_FLOW_MOD'] : self._receive_flow_mod,
            ofp_type_rev_map['OFPT_PACKET_OUT'] : self._receive_packet_out,
            ofp_type_rev_map['OFPT_BARRIER_REQUEST'] : \
                self._receive_barrier_request,
            ofp_type_rev_map['OFPT_GET_CONFIG_REQUEST'] : \
                self._receive_get_config_request,
            ofp_type_rev_map['OFPT_SET_CONFIG'] : self._receive_set_config,
            ofp_type_rev_map['OFPT_STATS_REQUEST'] : \
                self._receive_stats_request,
            ofp_type_rev_map['OFPT_VENDOR'] : self._receive_vendor,
            # Proactive responses
            ofp_type_rev_map['OFPT_ECHO_REPLY'] : self._receive_echo_reply
            # TODO: many more packet types to process
            }


        self._switch_connection = switch_connection
        if  not hasattr(switch_connection, '_dpid'): pdb.set_trace()

        # The controller sees VMOC as a switch. And we want each
        # connection to a controller to have a different DPID (or controllers
        # get confused). So VMOC has a different connection to a controller
        # by VLAN. And a controller may connect to multiple VMOCs.
        # So we need to construct a DPID that is unique over the space
        # of VLAN and switch_DPID.
        #
        # Here's what we do.
        # DPID's are 64 bits, of which the lower 48 are MAC addresses
        # and the top 16 are 'implementer defined' (Openflow spec).
        # The MAC should be unique and (for the contoller to talk to VMOC
        # we don't need to maintain the switch implementation features.
        # The vlan is 3 hex digits or 12 bits. 
        # So we take the VLAN and put it at the top three hex bytes of
        # the switch's DPID to form the VMOC-Controller-VLAN-specific DPIC
        #
        # VLAN in top 3 hex chars
        # Switch DPID in lower 13 hex chars
        controller_connection_dpid = \
            ((self._vlan & 0xfff) << 48) + \
            (switch_connection._dpid & 0x000fffffffffffff)  
        self._dpid = controller_connection_dpid

        self._url = url
        (host, port) = VMOCControllerConnection.parseURL(url)
        self._host = host;
        self._port = port
        self._sock = None

        # Make it optional to not open on create (for debugging at least)
        if open_on_create:
            self.open()

    def open(self):
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.connect((self._host, self._port))
        self.start()
        # When we have a new controller, send it a 'hello' (acting like
        # we are a switch to whom they are talking
        hello_msg = of.ofp_hello()
        self.send(hello_msg)

    def close(self):
#        print "CLOSING " + str(self)
        self._sock.close()
#        print "SOCKET CLOSED " + str(self)
        self._running = False
#        print "RUNNING = FALSE " + str(self)

    def __str__(self):
        return "[VMOCControllerConnection DPID %s URL %s VLAN %d]" % (self._dpid, self._url, self._vlan)

    def getURL(self):
        return self._url

    def getVLAN(self):
        return self._vlan

    def getSwitchConnection(self):
        return self._switch_connection

    def _receive_hello(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_HELLO")
#        log.debug("CC " +  str(ofp))

    def _receive_echo(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_ECHO_REQUEST")
#        log.debug("CC " +  str(ofp))
        echo_reply = ofp_echo_reply(xid=ofp.xid)
        self.send(echo_reply)

    def _receive_features_request(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_FEATURES_REQUEST")
#        log.debug("CC " +  str(ofp))
        switch = scmap.lookup_switch_for_controller_connection(self)
        features_reply = switch._features_reply
#        print "Features Request " + str(ofp.xid) + " " + str(features_reply.xid)
        features_reply.xid = ofp.xid
        self.send(features_reply)

    def _receive_flow_mod(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_FLOW_MOD")
#        log.debug("CC " +  str(ofp))
        # Need to forward this back to the switch
        self.forwardToAllAppropriateSwitches(ofp)

    def _receive_packet_out(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_PACKET_OUT")
        self.forwardToAllAppropriateSwitches(ofp)
#        log.debug("CC " +  str(ofp))

    def _receive_barrier_request(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_BARRIER_REQUEST")
#        log.debug("CC " +  str(ofp))
#        print "BARRIER ID " + str(ofp.xid)
        barrier_reply = ofp_barrier_reply(xid = ofp.xid)
#        print "BARRIER_REPLY = " + str(barrier_reply)
#        print "BARRIER_REQUEST = " + str(ofp)
        self.send(barrier_reply)

    def _receive_get_config_request(self, ofp):
        log.debug("CC " + self._url + " recvd " + \
                      "'OFPT_GET_CONFIG_REQUEST" + str(ofp))
        config_reply = ofp_get_config_reply(xid = ofp.xid)
#        log.debug("CC " + self._url + " recvd " + "'OFPT_GET_CONFIG_REQUEST ")
        log.debug("CONFIG %s" % (config_reply))
        self.send(config_reply)

    def _receive_set_config(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_SET_CONFIG")
#        log.debug("CC " + str(ofp))

    def _receive_stats_request(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_STATS_REQUEST " + str(ofp.type))
#        log.debug("CC " +  str(ofp))
        desc = ofp_desc_stats(mfr_desc="POX",
                              hw_desc=core._get_platform_info(),
                              sw_desc=core.version_string,
                              serial_num=str(self._dpid),
                              dp_desc=type(self).__name__)

        stats_reply = ofp_stats_reply(xid=ofp.xid, body=desc)
        self.send(stats_reply)

    def _receive_vendor(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_VENDOR")
#        log.debug("CC " +  str(ofp))

    def _receive_echo_reply(self, ofp):
        log.debug("CC " + self._url + " recvd " + "'OFPT_ECHO_REPLY")
#        log.debug("CC " +  str(ofp))

    # For now, forward the ofp to all switches assocaited with VMOC
{'fraction_non_alphanumeric': 0.10780711176437334, 'fraction_numerical': 0.003052744643563797, 'mean_word_length': 2.5845997973657546, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3502314', 'n_tokens_mistral': 5668, 'n_tokens_neox': 5407, 'n_words': 1495}