blob: ec70cc90887d77190502ecbb6e0eca882cd3aec3 [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"
Keita NISHIMOTO9617c852019-06-17 21:46:44 +090021 "net"
22 "strconv"
23
Matteo Scandolo88e91892018-11-06 16:29:19 -080024 "github.com/google/gopacket"
25 "github.com/google/gopacket/layers"
26 "github.com/google/gopacket/pcap"
Zack Williams2abf3932019-08-05 14:07:05 -070027 "github.com/opencord/voltha-bbsim/common/logger"
28 "github.com/opencord/voltha-bbsim/device"
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() {
Zdravko Bozakov078a2712019-07-19 23:25:15 +020036 logger.Debug("recv packet from IF: %v", *handler)
37 logger.Debug("Packet received %v", packet)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020038 // logger.Println(packet.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090039 pkt := Packet{}
40 pkt.Info = io
41 pkt.Pkt = packet
42 r <- pkt
43 }
44}
45
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020046// SendUni sends packet to UNI interface
Matteo Scandoloa286c742018-11-20 08:10:04 -080047func SendUni(handle *pcap.Handle, packet gopacket.Packet, onu *device.Onu) {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090048 err := handle.WritePacketData(packet.Data())
49 if err != nil {
Keita NISHIMOTO9617c852019-06-17 21:46:44 +090050 device.LoggerWithOnu(onu).Errorf("Error in send packet to UNI-IF: %v e:%v", *handle, err)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090051 }
Keita NISHIMOTO9617c852019-06-17 21:46:44 +090052 device.LoggerWithOnu(onu).Debugf("Successfully send packet to UNI-IF: %v", *handle)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090053}
54
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020055// SendNni sends packaet to NNI interface
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090056func SendNni(handle *pcap.Handle, packet gopacket.Packet) {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090057 err := handle.WritePacketData(packet.Data())
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090058 if err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080059 logger.Error("Error in send packet to NNI e:%s", err)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090060 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080061 logger.Debug("send packet to NNI-IF: %v ", *handle)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020062 // logger.Println(packet.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090063}
64
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020065// PopVLAN pops the vlan ans return packet
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090066func PopVLAN(pkt gopacket.Packet) (gopacket.Packet, uint16, error) {
67 if layer := getDot1QLayer(pkt); layer != nil {
68 if eth := getEthernetLayer(pkt); eth != nil {
69 ethernetLayer := &layers.Ethernet{
70 SrcMAC: eth.SrcMAC,
71 DstMAC: eth.DstMAC,
72 EthernetType: layer.Type,
73 }
74 buffer := gopacket.NewSerializeBuffer()
Zdravko Bozakov078a2712019-07-19 23:25:15 +020075 err := gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090076 ethernetLayer,
77 gopacket.Payload(layer.Payload),
78 )
Zdravko Bozakov078a2712019-07-19 23:25:15 +020079 if err != nil {
80 logger.Error("%v", err)
81 }
82
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090083 retpkt := gopacket.NewPacket(
84 buffer.Bytes(),
85 layers.LayerTypeEthernet,
86 gopacket.Default,
87 )
88 vid := uint16(4095 & layer.VLANIdentifier)
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +090089 logger.Debug("Pop the 802.1Q header (VID: %d)", vid)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090090 return retpkt, vid, nil
91 }
92 }
Scott Baker2b4ffb72019-08-02 16:20:47 -070093 return nil, 0, errors.New("failed to pop vlan")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090094}
95
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020096// PushVLAN pushes the vlan header to the packet and returns tha packet
Matteo Scandoloa286c742018-11-20 08:10:04 -080097func PushVLAN(pkt gopacket.Packet, vid uint16, onu *device.Onu) (gopacket.Packet, error) {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090098 if eth := getEthernetLayer(pkt); eth != nil {
99 ethernetLayer := &layers.Ethernet{
100 SrcMAC: eth.SrcMAC,
101 DstMAC: eth.DstMAC,
102 EthernetType: 0x8100,
103 }
104 dot1qLayer := &layers.Dot1Q{
105 Type: eth.EthernetType,
106 VLANIdentifier: uint16(vid),
107 }
108
109 buffer := gopacket.NewSerializeBuffer()
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200110 err := gopacket.SerializeLayers(
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900111 buffer,
112 gopacket.SerializeOptions{
113 FixLengths: false,
114 },
115 ethernetLayer,
116 dot1qLayer,
117 gopacket.Payload(eth.Payload),
118 )
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200119 if err != nil {
120 logger.Error("%v", err)
121 }
122
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900123 ret := gopacket.NewPacket(
124 buffer.Bytes(),
125 layers.LayerTypeEthernet,
126 gopacket.Default,
127 )
Keita NISHIMOTO9617c852019-06-17 21:46:44 +0900128 device.LoggerWithOnu(onu).Debugf("Push the 802.1Q header (VID: %d)", vid)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900129 return ret, nil
130 }
131 return nil, errors.New("failed to push vlan")
132}
133
134func getEthernetLayer(pkt gopacket.Packet) *layers.Ethernet {
135 eth := &layers.Ethernet{}
136 if ethLayer := pkt.Layer(layers.LayerTypeEthernet); ethLayer != nil {
137 eth, _ = ethLayer.(*layers.Ethernet)
138 }
139 return eth
140}
141func getDot1QLayer(pkt gopacket.Packet) (dot1q *layers.Dot1Q) {
142 if dot1qLayer := pkt.Layer(layers.LayerTypeDot1Q); dot1qLayer != nil {
143 dot1q = dot1qLayer.(*layers.Dot1Q)
144 }
145 return dot1q
146}
147
148func getMacAddress(ifName string) net.HardwareAddr {
149 var err error
150 var netIf *net.Interface
151 var hwAddr net.HardwareAddr
152 if netIf, err = net.InterfaceByName(ifName); err == nil {
153 hwAddr = netIf.HardwareAddr
154 }
155 return hwAddr
156}
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900157
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900158func makeNniName(oltid uint32) (upif string, dwif string) {
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200159 upif = NniVethNorthPfx + strconv.Itoa(int(oltid))
160 dwif = NniVethSouthPfx + strconv.Itoa(int(oltid))
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900161 return
162}
163
164func setupVethHandler(inveth string, outveth string, vethnames []string) (*pcap.Handle, []string, error) {
165 logger.Debug("SetupVethHandler(%s, %s) called ", inveth, outveth)
166 err1 := CreateVethPairs(inveth, outveth)
167 vethnames = append(vethnames, inveth)
168 if err1 != nil {
Zack Williamsb85f5932019-05-10 16:21:35 -0700169 logger.Error("setupVethHandler failed: %v", err1)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900170 RemoveVeths(vethnames)
171 return nil, vethnames, err1
172 }
173 handler, err2 := getVethHandler(inveth)
174 if err2 != nil {
Zack Williamsb85f5932019-05-10 16:21:35 -0700175 logger.Error("getVethHandler failed: %v", err2)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900176 RemoveVeths(vethnames)
177 return nil, vethnames, err2
178 }
179 return handler, vethnames, nil
180}
181
182func getVethHandler(vethname string) (*pcap.Handle, error) {
183 var (
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200184 deviceName = vethname
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200185 snapshotLen int32 = 1518
186 promiscuous = false
187 err error
Keita NISHIMOTO9617c852019-06-17 21:46:44 +0900188 timeout = pcap.BlockForever
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900189 )
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200190 handle, err := pcap.OpenLive(deviceName, snapshotLen, promiscuous, timeout)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900191 if err != nil {
192 return nil, err
193 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800194 logger.Debug("Server handle is created for %s", vethname)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900195 return handle, nil
196}