blob: 2657e4cd82a4cb88f7755129c5c0900400ee4152 [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 NISHIMOTO3b8b9c02018-10-09 09:40:01 +090021 "net"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090022 "strconv"
23 "time"
Matteo Scandolo88e91892018-11-06 16:29:19 -080024
25 "gerrit.opencord.org/voltha-bbsim/common/logger"
26 "github.com/google/gopacket"
27 "github.com/google/gopacket/layers"
28 "github.com/google/gopacket/pcap"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090029)
30
31func RecvWorker(io *Ioinfo, handler *pcap.Handle, r chan Packet) {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +090032 logger.Debug("recvWorker runs. handler: %v", *handler)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090033 packetSource := gopacket.NewPacketSource(handler, handler.LinkType())
34 for packet := range packetSource.Packets() {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080035 logger.Debug("recv packet from IF: %v ", *handler)
Matteo Scandolo88e91892018-11-06 16:29:19 -080036 //logger.Println(packet.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090037 pkt := Packet{}
38 pkt.Info = io
39 pkt.Pkt = packet
40 r <- pkt
41 }
42}
43
44func SendUni(handle *pcap.Handle, packet gopacket.Packet) {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090045 err := handle.WritePacketData(packet.Data())
46 if err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080047 logger.Error("Error in send packet to UNI-IF: %v e:%s", *handle, err)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090048 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080049 logger.Debug("Successfully send packet to UNI-IF: %v ", *handle)
Matteo Scandolo88e91892018-11-06 16:29:19 -080050 //logger.Println(packet.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090051}
52
53func SendNni(handle *pcap.Handle, packet gopacket.Packet) {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090054 err := handle.WritePacketData(packet.Data())
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090055 if err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080056 logger.Error("Error in send packet to NNI e:%s", err)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090057 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080058 logger.Debug("send packet to NNI-IF: %v ", *handle)
Matteo Scandolo88e91892018-11-06 16:29:19 -080059 //logger.Println(packet.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090060}
61
62func PopVLAN(pkt gopacket.Packet) (gopacket.Packet, uint16, error) {
63 if layer := getDot1QLayer(pkt); layer != nil {
64 if eth := getEthernetLayer(pkt); eth != nil {
65 ethernetLayer := &layers.Ethernet{
66 SrcMAC: eth.SrcMAC,
67 DstMAC: eth.DstMAC,
68 EthernetType: layer.Type,
69 }
70 buffer := gopacket.NewSerializeBuffer()
71 gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
72 ethernetLayer,
73 gopacket.Payload(layer.Payload),
74 )
75 retpkt := gopacket.NewPacket(
76 buffer.Bytes(),
77 layers.LayerTypeEthernet,
78 gopacket.Default,
79 )
80 vid := uint16(4095 & layer.VLANIdentifier)
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +090081 logger.Debug("Pop the 802.1Q header (VID: %d)", vid)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090082 return retpkt, vid, nil
83 }
84 }
Keita NISHIMOTOc864da22018-10-15 22:41:42 +090085 return pkt, 0, nil
86 //return nil, 0, errors.New("failed to pop vlan")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090087}
88
89func PushVLAN(pkt gopacket.Packet, vid uint16) (gopacket.Packet, error) {
90 if eth := getEthernetLayer(pkt); eth != nil {
91 ethernetLayer := &layers.Ethernet{
92 SrcMAC: eth.SrcMAC,
93 DstMAC: eth.DstMAC,
94 EthernetType: 0x8100,
95 }
96 dot1qLayer := &layers.Dot1Q{
97 Type: eth.EthernetType,
98 VLANIdentifier: uint16(vid),
99 }
100
101 buffer := gopacket.NewSerializeBuffer()
102 gopacket.SerializeLayers(
103 buffer,
104 gopacket.SerializeOptions{
105 FixLengths: false,
106 },
107 ethernetLayer,
108 dot1qLayer,
109 gopacket.Payload(eth.Payload),
110 )
111 ret := gopacket.NewPacket(
112 buffer.Bytes(),
113 layers.LayerTypeEthernet,
114 gopacket.Default,
115 )
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900116 logger.Debug("Push the 802.1Q header (VID: %d)", vid)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900117 return ret, nil
118 }
119 return nil, errors.New("failed to push vlan")
120}
121
122func getEthernetLayer(pkt gopacket.Packet) *layers.Ethernet {
123 eth := &layers.Ethernet{}
124 if ethLayer := pkt.Layer(layers.LayerTypeEthernet); ethLayer != nil {
125 eth, _ = ethLayer.(*layers.Ethernet)
126 }
127 return eth
128}
129func getDot1QLayer(pkt gopacket.Packet) (dot1q *layers.Dot1Q) {
130 if dot1qLayer := pkt.Layer(layers.LayerTypeDot1Q); dot1qLayer != nil {
131 dot1q = dot1qLayer.(*layers.Dot1Q)
132 }
133 return dot1q
134}
135
136func getMacAddress(ifName string) net.HardwareAddr {
137 var err error
138 var netIf *net.Interface
139 var hwAddr net.HardwareAddr
140 if netIf, err = net.InterfaceByName(ifName); err == nil {
141 hwAddr = netIf.HardwareAddr
142 }
143 return hwAddr
144}
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900145
146func makeUniName(oltid uint32, intfid uint32, onuid uint32) (upif string, dwif string) {
147 upif = UNI_VETH_UP_PFX + strconv.Itoa(int(oltid)) + "_" + strconv.Itoa(int(intfid)) + "_" + strconv.Itoa(int(onuid))
148 dwif = UNI_VETH_DW_PFX + strconv.Itoa(int(oltid)) + "_" + strconv.Itoa(int(intfid)) + "_" + strconv.Itoa(int(onuid))
149 return
150}
151
152func makeNniName(oltid uint32) (upif string, dwif string) {
153 upif = NNI_VETH_UP_PFX + strconv.Itoa(int(oltid))
154 dwif = NNI_VETH_DW_PFX + strconv.Itoa(int(oltid))
155 return
156}
157
158func setupVethHandler(inveth string, outveth string, vethnames []string) (*pcap.Handle, []string, error) {
159 logger.Debug("SetupVethHandler(%s, %s) called ", inveth, outveth)
160 err1 := CreateVethPairs(inveth, outveth)
161 vethnames = append(vethnames, inveth)
162 if err1 != nil {
163 RemoveVeths(vethnames)
164 return nil, vethnames, err1
165 }
166 handler, err2 := getVethHandler(inveth)
167 if err2 != nil {
168 RemoveVeths(vethnames)
169 return nil, vethnames, err2
170 }
171 return handler, vethnames, nil
172}
173
174func getVethHandler(vethname string) (*pcap.Handle, error) {
175 var (
176 device string = vethname
177 snapshot_len int32 = 1518
178 promiscuous bool = false
179 err error
180 timeout time.Duration = pcap.BlockForever
181 )
182 handle, err := pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
183 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}