-
Notifications
You must be signed in to change notification settings - Fork 299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vpn #86
Closed
Closed
Vpn #86
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
cce9cf5
Initial implementation of raw socket i/o using vhost.
alexandergall f0613cd
Added raw packet i/o for regular network devices.
alexandergall ebd92d2
- Basic OO support via the "class.lua" module.
alexandergall 26c51e9
- Added files that were not included in the previous commit by mistake.
alexandergall a4ac0fb
- Added portable support for bit fields
alexandergall 8d3b702
Merge remote-tracking branch 'upstream/master' into vpn
alexandergall 7e879f4
Update authorized_keys
alexandergall fc91865
First batch of performance tunings.
alexandergall 51122bb
Performance improvement by about a factor of 3
alexandergall 0e3116f
RawSocket: handle packets that are larger than a single buffer
alexandergall de1432b
Merge remote-tracking branch 'upstream/master'
alexandergall 411aabc
Merge branch 'master' into vpn
alexandergall 302f4ff
Adapted to new-style app configuration.
alexandergall 53aaaf6
Support for jumbo frames in intel10g. The limit is now given by
alexandergall 40813ed
Moved src/{class,strict}.lua to src/lib/lua.
alexandergall File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
-- This app acts as a responder for neighbor solicitaions for a | ||
-- specific target address and as a relay for all other packets. It | ||
-- has two ports, north and south. The south port attaches to a port | ||
-- on which NS messages are expected. Non-NS packets are sent on | ||
-- north. All packets received on the north port are passed south. | ||
|
||
local ffi = require("ffi") | ||
local app = require("core.app") | ||
local link = require("core.link") | ||
local packet = require("core.packet") | ||
local datagram = require("lib.protocol.datagram") | ||
local ethernet = require("lib.protocol.ethernet") | ||
local ipv6 = require("lib.protocol.ipv6") | ||
local icmp = require("lib.protocol.icmp.header") | ||
local ns = require("lib.protocol.icmp.nd.ns") | ||
|
||
local ns_responder = subClass(nil) | ||
|
||
function ns_responder:_init_new(config) | ||
self._config = config | ||
self._match = { { ethernet }, | ||
{ ipv6 }, | ||
{ icmp }, | ||
{ ns, | ||
function(ns) | ||
return(ns:target_eq(config.local_ip)) | ||
end } } | ||
end | ||
|
||
local function process(self, dgram) | ||
if dgram:parse(self._match) then | ||
local eth, ipv6, icmp, ns = unpack(dgram:stack()) | ||
local option = ns:options(dgram:payload()) | ||
if not (#option == 1 and option[1]:type() == 1) then | ||
-- Invalid NS, ignore | ||
return nil | ||
end | ||
-- Turn this message into a solicited neighbor | ||
-- advertisement with target ll addr option | ||
|
||
-- Ethernet | ||
eth:swap() | ||
eth:src(self._config.local_mac) | ||
|
||
-- IPv6 | ||
ipv6:dst(ipv6:src()) | ||
ipv6:src(self._config.local_ip) | ||
|
||
-- ICMP | ||
option[1]:type(2) | ||
option[1]:option():addr(self._config.local_mac) | ||
icmp:type(136) | ||
-- Undo/redo icmp and ns headers to get | ||
-- payload and set solicited flag | ||
dgram:unparse(2) | ||
dgram:parse() -- icmp | ||
local payload, length = dgram:payload() | ||
dgram:parse():solicited(1) | ||
icmp:checksum(payload, length, ipv6) | ||
return true | ||
end | ||
return false | ||
end | ||
|
||
function ns_responder:push() | ||
local l_in = self.input.north | ||
local l_out = self.output.south | ||
assert(l_in and l_out) | ||
while not link.empty(l_in) and not link.full(l_out) do | ||
-- Pass everything on north -> south | ||
link.transmit(l_out, link.receive(l_in)) | ||
end | ||
l_in = self.input.south | ||
l_out = self.output.north | ||
local l_reply = self.output.south | ||
while not link.empty(l_in) and not link.full(l_out) do | ||
local p = link.receive(l_in) | ||
local datagram = datagram:new(p, ethernet) | ||
local status = process(self, datagram) | ||
if status == nil then | ||
-- Discard | ||
packet.deref(p) | ||
elseif status == true then | ||
-- Send NA back south | ||
link.transmit(l_reply, p) | ||
else | ||
-- Send transit traffic up north | ||
link.transmit(l_out, p) | ||
end | ||
end | ||
end | ||
|
||
return ns_responder |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
module(...,package.seeall) | ||
|
||
local ffi = require("ffi") | ||
local C = ffi.C | ||
|
||
local buffer = require("core.buffer") | ||
local packet = require("core.packet") | ||
require("lib.raw.raw_h") | ||
require("apps.socket.io_h") | ||
|
||
dev = {} | ||
|
||
function dev:new(ifname) | ||
assert(ifname) | ||
self.__index = self | ||
local dev = { fd = C.open_raw(ifname) } | ||
return setmetatable(dev, self) | ||
end | ||
|
||
function dev:transmit(p) | ||
assert(self.fd) | ||
assert(C.send_packet(self.fd, p) ~= -1) | ||
end | ||
|
||
function dev:can_transmit() | ||
return C.can_transmit(self.fd) == 1 | ||
end | ||
|
||
function dev:receive() | ||
assert(self.fd) | ||
local size = C.msg_size(self.fd) | ||
assert(size ~= -1) | ||
local p = packet.allocate() | ||
local nbuffers = math.ceil(size/buffer.size) | ||
assert(nbuffers <= C.PACKET_IOVEC_MAX) | ||
for i = 1, nbuffers do | ||
local b = buffer.allocate() | ||
packet.add_iovec(p, b, 0) | ||
end | ||
local s = C.receive_packet(self.fd, p) | ||
assert(s ~= -1) | ||
return p | ||
end | ||
|
||
function dev:can_receive() | ||
return C.can_receive(self.fd) == 1 | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#include <sys/types.h> | ||
#include <sys/socket.h> | ||
#include <sys/time.h> | ||
#include <sys/ioctl.h> | ||
#include <unistd.h> | ||
#include <stdint.h> | ||
#include <strings.h> | ||
#include <stdio.h> | ||
#include <errno.h> | ||
#include "core/packet.h" | ||
|
||
int send_packet(int fd, struct packet *p) { | ||
struct msghdr msg; | ||
struct iovec iovecs[PACKET_IOVEC_MAX]; | ||
int i, n = p->niovecs; | ||
|
||
bzero(&msg, sizeof(msg)); | ||
for (i=0; i < n; i++) { | ||
struct packet_iovec *piov = &p->iovecs[i]; | ||
struct iovec *iov = &iovecs[i]; | ||
|
||
iov->iov_base = piov->buffer->pointer + piov->offset; | ||
iov->iov_len = piov->length; | ||
} | ||
msg.msg_iov = &iovecs[0]; | ||
msg.msg_iovlen = n; | ||
|
||
if (sendmsg(fd, &msg, 0) == -1) { | ||
perror("sendmsg"); | ||
return(-1); | ||
} | ||
return(0); | ||
} | ||
|
||
int receive_packet(int fd, struct packet *p) { | ||
struct msghdr msg; | ||
struct iovec iovecs[p->niovecs]; | ||
int i; | ||
ssize_t s, len; | ||
|
||
bzero(&msg, sizeof(msg)); | ||
for (i=0; i<p->niovecs; i++) { | ||
iovecs[i].iov_base = p->iovecs[i].buffer->pointer; | ||
iovecs[i].iov_len = p->iovecs[i].buffer->size; | ||
} | ||
msg.msg_iov = iovecs; | ||
msg.msg_iovlen = p->niovecs; | ||
if ((s = recvmsg(fd, &msg, 0)) == -1) { | ||
perror("recvmsg"); | ||
return(-1); | ||
} | ||
if (msg.msg_flags && MSG_TRUNC) { | ||
printf("truncated\n"); | ||
return(-1); | ||
} | ||
len = s; | ||
for (i=0; i<p->niovecs; i++) { | ||
ssize_t iov_len = msg.msg_iov[i].iov_len; | ||
if (len > iov_len) { | ||
p->iovecs[i].length = iov_len; | ||
len -= iov_len; | ||
} else { | ||
p->iovecs[i].length = len; | ||
} | ||
} | ||
p->length = s; | ||
return(s); | ||
} | ||
|
||
int msg_size(int fd) { | ||
int size; | ||
if (ioctl(fd, FIONREAD, &size) == -1) { | ||
perror("get message size"); | ||
return(-1); | ||
} | ||
return(size); | ||
} | ||
|
||
int can_receive(int fd) { | ||
fd_set fds; | ||
struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; | ||
int result; | ||
|
||
FD_ZERO(&fds); | ||
FD_SET(fd, &fds); | ||
if ((result = select(fd+1, &fds, NULL, NULL, &tv)) == -1) { | ||
perror("select"); | ||
return(-1); | ||
} | ||
return(result); | ||
} | ||
|
||
int can_transmit(int fd) { | ||
fd_set fds; | ||
struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; | ||
int result; | ||
|
||
FD_ZERO(&fds); | ||
FD_SET(fd, &fds); | ||
if ((result = select(fd+1, NULL, &fds, NULL, &tv)) == -1) { | ||
perror("select"); | ||
return(-1); | ||
} | ||
return(result); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
int send_packet(int, struct packet *); | ||
int receive_packet(int, struct packet *); | ||
int can_transmit(int); | ||
int can_receive(int); | ||
int msg_size(int); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love this design idea: to handle neighbor solicitation response as a small discrete app that "does one thing well" instead of adding it as a feature to the IPv6 next-hop-routing app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, the traffic going north->south is passed through untouched. Would it make sense to bypass the app in that direction to avoid the overhead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder about that too. I suppose it will be worth doing that kind of stuff if the performance difference is significant in practice, once we are done with optimization. I hope we will have the basic app transmit/receive functionality so fast that we don't need to care.