diff --git a/src/README.md b/src/README.md index 92ed940bed..9bfd118529 100644 --- a/src/README.md +++ b/src/README.md @@ -303,35 +303,41 @@ Returns a structure holding ring statistics for the *link*: ## Packet (core.packet) - -A *packet* is a data structure describing one of the network packets that -is currently being processed. The packet is used to explicitly manage the -life cycle of the packet. Packets are explicitly allocated and freed by -using `packet.allocate` and `packet.free`. When a packet is received -using `link.receive` its ownership is acquired by the calling app. The -app must then ensure to either transfer the packet ownership to another -app by calling `link.transmit` on the packet or free the packet using -`packet.free`. Apps may only use packets they own, e.g. packets that have -not been transmitted or freed. The number of allocatable packets is -limited by the size of the underlying "freelist", e.g. a pool of unused -packet objects from and to which packets are allocated and freed. -— Function **packet.allocate** +A *packet* is an FFI object of type `packet.packet_t` representing a network +packet that is currently being processed. The packet is used to explicitly +manage the life cycle of the packet. Packets are explicitly allocated and freed +by using `packet.allocate` and `packet.free`. When a packet is received using +`link.receive` its ownership is acquired by the calling app. The app must then +ensure to either transfer the packet ownership to another app by calling +`link.transmit` on the packet or free the packet using `packet.free`. Apps may +only use packets they own, e.g. packets that have not been transmitted or +freed. The number of allocatable packets is limited by the size of the +underlying “freelist”, e.g. a pool of unused packet objects from and to which +packets are allocated and freed. -Returns a new empty packet. An an error is raised if there are no packets -left on the freelist. +— Ctype **packet.packet_t** -— Function **packet.free** *packet* +``` +struct packet { + uint8_t data[packet.max_payload]; + uint16_t length; +}; +``` -Frees *packet* and puts in back onto the freelist. +— Constant **packet.max_payload** -— Function **packet.data** *packet* +The maximum payload length of a packet. -Returns a pointer to the payload of *packet*. +— Function **packet.allocate** -— Function **packet.length** *packet* +Returns a new empty packet. An an error is raised if there are no packets left +on the freelist. Initially the `length` of the allocated is 0, and its `data` +is uninitialized garbage. -Returns the payload length of *packet*. +— Function **packet.free** *packet* + +Frees *packet* and puts in back onto the freelist. — Function **packet.clone** *packet* @@ -357,7 +363,14 @@ accomodate *length* additional bytes. — Function **packet.shiftleft** *packet*, *length* -Truncates *packet* by *length* bytes from the front. +Truncates *packet* by *length* bytes from the front. *Length* must be less than +or equal to `length` of *packet*. + +— Function **packet.shiftright** *packet*, *length* + +Move *packet* payload to the right by *length* bytes, growing *packet* by +*length*. The sum of *length* and `length` of *packet* must be less than or +equal to `packet.max_payload`. — Function **packet.from_pointer** *pointer*, *length* diff --git a/src/apps/bridge/learning.lua b/src/apps/bridge/learning.lua index a372b78137..0edb4a0365 100644 --- a/src/apps/bridge/learning.lua +++ b/src/apps/bridge/learning.lua @@ -203,7 +203,7 @@ function bridge:push() -- packet with one of the packet forwarding tables according -- to the result. local mac = self._mac - mac[0] = packet.data(p) + mac[0] = p.data mac_table:lookup_pft(mac, ip, ig, p, self._pft_C, self._flood_pl[ip]) -- Associate the source MAC address with the ingress port and -- group. Multicast addresses are forbidden to occur as diff --git a/src/apps/ipv6/nd_light.lua b/src/apps/ipv6/nd_light.lua index 2717338d68..152e55455e 100644 --- a/src/apps/ipv6/nd_light.lua +++ b/src/apps/ipv6/nd_light.lua @@ -256,7 +256,7 @@ local function na (self, dgram, eth, ipv6, icmp) end local function from_south (self, p) - if not self._filter:match(packet.data(p[0]), packet.length(p[0])) then + if not self._filter:match(p[0].data, p[0].length) then return false end local dgram = datagram:new(p[0], ethernet) @@ -314,8 +314,8 @@ function nd_light:push () else local p = cache.p p[0] = link.receive(l_in) - if packet.length(p[0]) >= self._eth_header:sizeof() then - self._eth_header:copy(packet.data(p[0])) + if p[0].length >= self._eth_header:sizeof() then + self._eth_header:copy(p[0].data) link.transmit(l_out, p[0]) else packet.free(p[0]) end end diff --git a/src/apps/ipv6/ns_responder.lua b/src/apps/ipv6/ns_responder.lua index a23a5151d6..e61b575a7d 100644 --- a/src/apps/ipv6/ns_responder.lua +++ b/src/apps/ipv6/ns_responder.lua @@ -36,7 +36,7 @@ function ns_responder:new(config) end local function process (self, p) - if not self._filter:match(packet.data(p), packet.length(p)) then + if not self._filter:match(p.data, p.length) then return false end local dgram = self._dgram:new(p, ethernet) diff --git a/src/apps/test/match.lua b/src/apps/test/match.lua index 48427d50bc..649bc4803f 100644 --- a/src/apps/test/match.lua +++ b/src/apps/test/match.lua @@ -5,7 +5,7 @@ local C = ffi.C local lib = require("core.lib") local function dump (p) - return lib.hexdump(ffi.string(packet.data(p), packet.length(p))) + return lib.hexdump(ffi.string(p.data, p.length)) end Match = {} @@ -24,8 +24,8 @@ function Match:push () local p = link.receive(self.input.rx) local cmp = link.front(self.input.comparator) if not cmp then - elseif packet.length(cmp) ~= packet.length(p) - or C.memcmp(packet.data(cmp), packet.data(p), packet.length(cmp)) ~= 0 then + elseif cmp.length ~= p.length + or C.memcmp(cmp.data, p.data, cmp.length) ~= 0 then if not self.fuzzy then table.insert(self.errs, "Mismatch:\n"..dump(cmp).."\n"..dump(p)) end diff --git a/src/apps/vlan/vlan.lua b/src/apps/vlan/vlan.lua index 763017beb8..3ec4b6b2d3 100644 --- a/src/apps/vlan/vlan.lua +++ b/src/apps/vlan/vlan.lua @@ -48,7 +48,7 @@ end -- packet is carrying a VLAN tag, if it's an untagged frame these bytes will be -- Ethernet payload function extract_tci(pkt) - return ntohs(cast("uint16_t*", packet.data(pkt) + o_ethernet_ethertype + 2)[0]) + return ntohs(cast("uint16_t*", pkt.data + o_ethernet_ethertype + 2)[0]) end -- extract VLAN id from TCI @@ -120,7 +120,7 @@ function VlanMux:push() if type(name) == "string" then for _ = 1, math.min(link.nreadable(l), maxoutput) do local p = receive(l) - local ethertype = cast("uint16_t*", packet.data(p) + o_ethernet_ethertype)[0] + local ethertype = cast("uint16_t*", p.data + o_ethernet_ethertype)[0] if name == "trunk" then -- trunk -- check for ethertype 0x8100 (802.1q VLAN tag) diff --git a/src/lib/ipsec/esp.lua b/src/lib/ipsec/esp.lua index 23ba7b4c6a..d7c668acad 100644 --- a/src/lib/ipsec/esp.lua +++ b/src/lib/ipsec/esp.lua @@ -86,7 +86,7 @@ local function padding (a, l) return (a - l%a) % a end -- 5. Write ESP header function esp_v6_encrypt:encapsulate (p) local gcm = self.aes_128_gcm - local data, length = packet.data(p), packet.length(p) + local data, length = p.data, p.length if length < PAYLOAD_OFFSET then return false end local payload = data + PAYLOAD_OFFSET local payload_length = length - PAYLOAD_OFFSET @@ -134,7 +134,7 @@ end -- 5. Shrink p by ESP overhead function esp_v6_decrypt:decapsulate (p) local gcm = self.aes_128_gcm - local data, length = packet.data(p), packet.length(p) + local data, length = p.data, p.length if length - PAYLOAD_OFFSET < self.MIN_SIZE then return false end self.ip:new_from_mem(data + ETHERNET_SIZE, IPV6_SIZE) local payload = data + PAYLOAD_OFFSET @@ -176,20 +176,19 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ ) local d = datagram:new(payload) local ip = ipv6:new({}) - ip:payload_length(packet.length(payload)) + ip:payload_length(payload.length) d:push(ip) d:push(ethernet:new({type=0x86dd})) local p = d:packet() -- Check integrity - print("original", lib.hexdump(ffi.string(packet.data(p), packet.length(p)))) + print("original", lib.hexdump(ffi.string(p.data, p.length))) local p_enc = packet.clone(p) assert(enc:encapsulate(p_enc), "encapsulation failed") - print("encrypted", lib.hexdump(ffi.string(packet.data(p_enc), packet.length(p_enc)))) + print("encrypted", lib.hexdump(ffi.string(p_enc.data, p_enc.length))) local p2 = packet.clone(p_enc) assert(dec:decapsulate(p2), "decapsulation failed") - print("decrypted", lib.hexdump(ffi.string(packet.data(p2), packet.length(p2)))) - assert(packet.length(p2) == packet.length(p) - and C.memcmp(p, p2, packet.length(p)) == 0, + print("decrypted", lib.hexdump(ffi.string(p2.data, p2.length))) + assert(p2.length == p.length and C.memcmp(p, p2, p.length) == 0, "integrity check failed") -- Check invalid packets. local p_invalid = packet.from_string("invalid") diff --git a/src/lib/protocol/README.md b/src/lib/protocol/README.md index 4a13483a4b..6cf8ce19ea 100644 --- a/src/lib/protocol/README.md +++ b/src/lib/protocol/README.md @@ -813,9 +813,7 @@ If *pointer* and *length* are supplied then *length* bytes starting from — Method **datagram:data** -Returns the location and size of the buffer of the underlying packet. -This is a shortcut to *datagram:packet* followed by calls to -*packet.data* and *pakcet.length*. +Returns `data` and `length` of the underlying packet. - Method **datagram:commit** diff --git a/src/lib/protocol/datagram.lua b/src/lib/protocol/datagram.lua index 91d778fb71..f2b180e64c 100644 --- a/src/lib/protocol/datagram.lua +++ b/src/lib/protocol/datagram.lua @@ -180,8 +180,8 @@ function datagram:parse_match (class, check) local parse = self._parse local class = class or parse.ulp if not class then return nil end - local proto = class:new_from_mem(packet.data(self._packet[0]) + parse.offset, - packet.length(self._packet[0]) - parse.offset) + local proto = class:new_from_mem(self._packet[0].data + parse.offset, + self._packet[0].length - parse.offset) if proto == nil or (check and not check(proto)) then if proto then proto:free() end return nil @@ -295,14 +295,14 @@ end -- appended to the packet's payload first. function datagram:payload (mem, size) if mem then packet.append(self._packet[0], mem, size) end - return packet.data(self._packet[0]) + self._parse.offset, - packet.length(self._packet[0]) - self._parse.offset + return self._packet[0].data + self._parse.offset, + self._packet[0].length - self._parse.offset end -- Return the location and size of the entire packet buffer function datagram:data () local p = self._packet - return packet.data(p[0]), packet.length(p[0]) + return p[0].data, p[0].length end -- Commit the changes induced by previous calles to the push*() and