blob: c59b903a0a899aa1e84ffcb241d37434c8fbfe09 [file] [log] [blame]
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +09001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package core
18
19import (
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090020 "errors"
Matteo Scandolo88e91892018-11-06 16:29:19 -080021 "gerrit.opencord.org/voltha-bbsim/common/logger"
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020022 "gerrit.opencord.org/voltha-bbsim/common/utils"
23 "gerrit.opencord.org/voltha-bbsim/device"
Matteo Scandolo88e91892018-11-06 16:29:19 -080024 "github.com/google/gopacket"
25 "github.com/google/gopacket/layers"
26 "github.com/google/gopacket/pcap"
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020027 "net"
28 "strconv"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090029)
30
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020031// RecvWorker receives the packet and forwards to the channel
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090032func RecvWorker(io *Ioinfo, handler *pcap.Handle, r chan Packet) {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +090033 logger.Debug("recvWorker runs. handler: %v", *handler)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090034 packetSource := gopacket.NewPacketSource(handler, handler.LinkType())
35 for packet := range packetSource.Packets() {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080036 logger.Debug("recv packet from IF: %v ", *handler)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020037 // logger.Println(packet.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090038 pkt := Packet{}
39 pkt.Info = io
40 pkt.Pkt = packet
41 r <- pkt
42 }
43}
44
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020045// SendUni sends packet to UNI interface
Matteo Scandoloa286c742018-11-20 08:10:04 -080046func SendUni(handle *pcap.Handle, packet gopacket.Packet, onu *device.Onu) {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090047 err := handle.WritePacketData(packet.Data())
48 if err != nil {
Zack Williamsb85f5932019-05-10 16:21:35 -070049 utils.LoggerWithOnu(onu).Errorf("Error in send packet to UNI-IF: %v e:%v", *handle, err)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090050 }
Zack Williamsb85f5932019-05-10 16:21:35 -070051 utils.LoggerWithOnu(onu).Debugf("Successfully send packet to UNI-IF: %v", *handle)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090052}
53
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020054// SendNni sends packaet to NNI interface
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090055func SendNni(handle *pcap.Handle, packet gopacket.Packet) {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090056 err := handle.WritePacketData(packet.Data())
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090057 if err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080058 logger.Error("Error in send packet to NNI e:%s", err)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090059 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080060 logger.Debug("send packet to NNI-IF: %v ", *handle)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020061 // logger.Println(packet.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090062}
63
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020064// PopVLAN pops the vlan ans return packet
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090065func PopVLAN(pkt gopacket.Packet) (gopacket.Packet, uint16, error) {
66 if layer := getDot1QLayer(pkt); layer != nil {
67 if eth := getEthernetLayer(pkt); eth != nil {
68 ethernetLayer := &layers.Ethernet{
69 SrcMAC: eth.SrcMAC,
70 DstMAC: eth.DstMAC,
71 EthernetType: layer.Type,
72 }
73 buffer := gopacket.NewSerializeBuffer()
74 gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
75 ethernetLayer,
76 gopacket.Payload(layer.Payload),
77 )
78 retpkt := gopacket.NewPacket(
79 buffer.Bytes(),
80 layers.LayerTypeEthernet,
81 gopacket.Default,
82 )
83 vid := uint16(4095 & layer.VLANIdentifier)
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +090084 logger.Debug("Pop the 802.1Q header (VID: %d)", vid)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090085 return retpkt, vid, nil
86 }
87 }
Keita NISHIMOTOc864da22018-10-15 22:41:42 +090088 return pkt, 0, nil
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020089 // return nil, 0, errors.New("failed to pop vlan")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090090}
91
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020092// PushVLAN pushes the vlan header to the packet and returns tha packet
Matteo Scandoloa286c742018-11-20 08:10:04 -080093func PushVLAN(pkt gopacket.Packet, vid uint16, onu *device.Onu) (gopacket.Packet, error) {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090094 if eth := getEthernetLayer(pkt); eth != nil {
95 ethernetLayer := &layers.Ethernet{
96 SrcMAC: eth.SrcMAC,
97 DstMAC: eth.DstMAC,
98 EthernetType: 0x8100,
99 }
100 dot1qLayer := &layers.Dot1Q{
101 Type: eth.EthernetType,
102 VLANIdentifier: uint16(vid),
103 }
104
105 buffer := gopacket.NewSerializeBuffer()
106 gopacket.SerializeLayers(
107 buffer,
108 gopacket.SerializeOptions{
109 FixLengths: false,
110 },
111 ethernetLayer,
112 dot1qLayer,
113 gopacket.Payload(eth.Payload),
114 )
115 ret := gopacket.NewPacket(
116 buffer.Bytes(),
117 layers.LayerTypeEthernet,
118 gopacket.Default,
119 )
Matteo Scandoloa286c742018-11-20 08:10:04 -0800120 utils.LoggerWithOnu(onu).Debugf("Push the 802.1Q header (VID: %d)", vid)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900121 return ret, nil
122 }
123 return nil, errors.New("failed to push vlan")
124}
125
126func getEthernetLayer(pkt gopacket.Packet) *layers.Ethernet {
127 eth := &layers.Ethernet{}
128 if ethLayer := pkt.Layer(layers.LayerTypeEthernet); ethLayer != nil {
129 eth, _ = ethLayer.(*layers.Ethernet)
130 }
131 return eth
132}
133func getDot1QLayer(pkt gopacket.Packet) (dot1q *layers.Dot1Q) {
134 if dot1qLayer := pkt.Layer(layers.LayerTypeDot1Q); dot1qLayer != nil {
135 dot1q = dot1qLayer.(*layers.Dot1Q)
136 }
137 return dot1q
138}
139
140func getMacAddress(ifName string) net.HardwareAddr {
141 var err error
142 var netIf *net.Interface
143 var hwAddr net.HardwareAddr
144 if netIf, err = net.InterfaceByName(ifName); err == nil {
145 hwAddr = netIf.HardwareAddr
146 }
147 return hwAddr
148}
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900149
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900150func makeNniName(oltid uint32) (upif string, dwif string) {
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200151 upif = NniVethNorthPfx + strconv.Itoa(int(oltid))
152 dwif = NniVethSouthPfx + strconv.Itoa(int(oltid))
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900153 return
154}
155
156func setupVethHandler(inveth string, outveth string, vethnames []string) (*pcap.Handle, []string, error) {
157 logger.Debug("SetupVethHandler(%s, %s) called ", inveth, outveth)
158 err1 := CreateVethPairs(inveth, outveth)
159 vethnames = append(vethnames, inveth)
160 if err1 != nil {
Zack Williamsb85f5932019-05-10 16:21:35 -0700161 logger.Error("setupVethHandler failed: %v", err1)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900162 RemoveVeths(vethnames)
163 return nil, vethnames, err1
164 }
165 handler, err2 := getVethHandler(inveth)
166 if err2 != nil {
Zack Williamsb85f5932019-05-10 16:21:35 -0700167 logger.Error("getVethHandler failed: %v", err2)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900168 RemoveVeths(vethnames)
169 return nil, vethnames, err2
170 }
171 return handler, vethnames, nil
172}
173
174func getVethHandler(vethname string) (*pcap.Handle, error) {
175 var (
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200176 device = vethname
177 snapshotLen int32 = 1518
178 promiscuous = false
179 err error
180 timeout = pcap.BlockForever
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900181 )
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200182 handle, err := pcap.OpenLive(device, snapshotLen, promiscuous, timeout)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900183 if err != nil {
184 return nil, err
185 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800186 logger.Debug("Server handle is created for %s", vethname)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900187 return handle, nil
188}