LLDP数据包中添加自定义LLDPDU

在LLDP数据包中添加自定义LLDPDU

如何在LLDP数据包中携带发送时间戳
LLDP描述文件:ryu/lib/packet/lldp.py

一、lldp.py

  1. 增添 TLV 类型
  2. 增添 TimeStamp 类
  3. lldp 类的修改

1.1 lldp.py :增添TLV类型:TimeStamp

  # LLDP TLV type
  LLDP_TLV_END = 0                        # End of LLDPDU
  LLDP_TLV_CHASSIS_ID = 1                 # Chassis ID
  LLDP_TLV_PORT_ID = 2                    # Port ID
  LLDP_TLV_TTL = 3                        # Time To Live
  LLDP_TLV_PORT_DESCRIPTION = 4           # Port Description
  LLDP_TLV_SYSTEM_NAME = 5                # System Name
  LLDP_TLV_SYSTEM_DESCRIPTION = 6         # System Description
  LLDP_TLV_SYSTEM_CAPABILITIES = 7        # System Capabilities
  LLDP_TLV_MANAGEMENT_ADDRESS = 8         # Management Address
  LLDP_TLV_ORGANIZATIONALLY_SPECIFIC = 127  # organizationally Specific TLVs
  LLDP_TLV_SEND_TIME = 11  # Time stamp for sending LLDP packet, using for delay measurement.

增添发送时间戳:LLDP_TLV_SEND_TIME = 11 ,用于解析

1.2 lldp.py :增添 TimeStamp 类

参考lldp.py中的 TTL 类

@lldp.set_tlv_type(LLDP_TLV_SEND_TIME)
class TimeStamp(LLDPBasicTLV):
    _PACK_STR = '!d'
    _PACK_SIZE = struct.calcsize(_PACK_STR)
    _LEN_MIN = _PACK_SIZE
    _LEN_MAX = _PACK_SIZE
  
    def __init__(self, buf=None, *args, **kwargs):
        super(TimeStamp, self).__init__(buf, *args, **kwargs)
        if buf:
        (self.timestamp, ) = struct.unpack(
                self._PACK_STR, self.tlv_info[:self._PACK_SIZE])
        else:
            self.timestamp = kwargs['timestamp']
            self.len = self._PACK_SIZE
            assert self._len_valid()
            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len

        def serialize(self):
            return struct.pack('!Hd', self.typelen, self.timestamp)

1.3 lldp.py : lldp 类的修改

去掉最后一项,即不判断最后一个为END

def _tlvs_valid(self):
    return (self.tlvs[0].tlv_type == LLDP_TLV_CHASSIS_ID and
      self.tlvs[1].tlv_type == LLDP_TLV_PORT_ID and
      self.tlvs[2].tlv_type == LLDP_TLV_TTL)

修改 break 条件

def _parser(cls, buf)
    tlvs = []
    while buf:
        tlv_type = LLDPBasicTlv.get_type(buf)
        tlv = cls._tlv_parsers[tlv_type](buf)
        tlvs.append(tlv)
        offset = LLDP_TLV_SIZE + tlv.len
        buf = buf[offset:]
        if tlv.tlv_type == LLDP_TLV_SEND_TIME: # END 改为LLDP_TLV_SEND_TIME
            break
        assert len(buf) > 0
    lldp_pkt = cls(tlvs)
    assert lldp_pkt._tlvs_len_valid()
    assert lldp_pkt._tlvs_valid()
    return lldp_pkt, None, buf

二、switches.py:

  1. switches.py文件中的LLDPPacket类完成了LLDP数据包的初始化和序列化实现
  2. lldp_packet方法可以构造LLDP数据包,并返回序列化之后的数据。在此函数中,我们需要添加timestamp的TLV
  3. lldp_parse:将获取到的字节流的数据解析为对应的LLDP数据包,由于在发送之前,我们加入了一个timestamp的TLV,所以解析时需要完成这个TLV的解析,并将TimeStamp作为返回值返回

2.1、switches.py:@staticmethod lldp_packet

1. 增添方法的参数 timestamp

def lldp_packet(dpid, port_no, dl_addr, ttl, timestamp):

2. 增添 Timestamp 属性

tlv_ttl = lldp.TTL(ttl=ttl)
tlv_timestamp = lldp.TimeStamp(timestamp=timestamp)
tlv_end = lldp.End()

3. 修改tlvs:增添 timestamp 参数

 tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_timestamp, tlv_end)

2.2、switches.py:@staticmethod lldp_parse

tlv_timestamp = lldp_pkt.tlvs[11]
timestamp = tlv_timestamp
return  src_dpid, src_port_no, timestamp,

解析取出timestamp,要与之前LLDP声明的一致,之前声明的为11

2.3、switches.py: def _port_added 修改:增加时间戳

def _port_added(self, port):
    _time = time.time()
    lldp_data = LLDPPacket.lldp_packet(port.dpid, port.port_no,
                       port.hw_addr, self.DEFAULT_TTL, _time)

第二处:

LLDP_PACKET_LEN = len(LLDPPacket.lldp_packet(0, 0, DONTCARE_STR, 0, 0))

2.4 switches.py:增添返回的变量

调用了lldp_parse方法的地方,返回的值都要增添一个timestamp

src_dpid, src_port_no, timestamp = LLDPPacket.lldp_parse(msg.data)

2.5 发送LLDP报文出修改,每次重新插入时间戳

  def send_lldp_packet(self, port):
    try:
      port_data = self.ports.lldp_sent(port)
    except KeyError:
      # ports can be modified during our sleep in self.lldp_loop()
      # LOG.debug('send_lld error', exc_info=True)
      return
    if port_data.is_down:
      return

    dp = self.dps.get(port.dpid, None)
    if dp is None:
      # datapath was already deleted
      return
    timestamp = time.time()
    lldp_data = LLDPPacket.lldp_packet(
      port.dpid, port.port_no, port.hw_addr, self.DEFAULT_TTL, timestamp)
    # LOG.debug('lldp sent dpid=%s, port_no=%d', dp.id, port.port_no)
    # TODO:XXX
    if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
      actions = [dp.ofproto_parser.OFPActionOutput(port.port_no)]
      dp.send_packet_out(actions=actions, data=lldp_data)
    elif dp.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION:
      actions = [dp.ofproto_parser.OFPActionOutput(port.port_no)]
      out = dp.ofproto_parser.OFPPacketOut(
        datapath=dp, in_port=dp.ofproto.OFPP_CONTROLLER,
        buffer_id=dp.ofproto.OFP_NO_BUFFER, actions=actions,
        data=lldp_data)
      dp.send_msg(out)
    #print port_data #cat
    else:
      LOG.error('cannot send lldp packet. unsupported version. %x',
            dp.ofproto.OFP_VERSION)

注意

在Ryu的Switches模块中,被发送的LLDP都是一次构造之后保存起来,发送时直接发送的,所以添加的时间戳会固定在第一次构造时的时间。所以如果希望正确地插入发送时间戳,还需要进行额外的逻辑修改。但是这也许就破坏了Ryu设计的完整性,所以如何操作还需要读者自行斟酌。

参考:李呈: Ryu:如何在LLDP中添加自定义LLDPDU

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容