Skip to content

Commit

Permalink
Reworked vrr_create() and vrr_sendmsg(). Data packets are now routed
Browse files Browse the repository at this point in the history
for sending using routing table information.
  • Loading branch information
tadfisher committed Aug 6, 2010
1 parent a3e146c commit a80c0ab
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 103 deletions.
129 changes: 67 additions & 62 deletions af_vrr.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
#include <net/sock.h>

#include "vrr.h"
#include "vrr_data.h"

static int __vrr_connect(struct sock *sk, struct sockaddr_vrr *addr,
int addrlen, long *timeo, int flags)
{
struct socket *sock = sk->sk_socket;
struct vrr_sock *vrr = vrr_sk(sk);
int err = -EISCONN;

if (sock->state == SS_CONNECTED) {
Expand All @@ -48,9 +48,8 @@ static int __vrr_connect(struct sock *sk, struct sockaddr_vrr *addr,
if (addr->svrr_family != AF_VRR)
goto out;

sock->state = SS_CONNECTED;
err = 0;
vrr->src_addr = get_vrr_id();
vrr->dest_addr = addr->svrr_addr;

out:
return err;
Expand All @@ -75,7 +74,6 @@ static int vrr_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags)
{
struct sock *sk = sock->sk;
// struct vrr_sock *vrr = vrr_sk(sk);
struct sockaddr_vrr *svrr = (struct sockaddr_vrr *)msg->msg_name;
struct sk_buff *skb;
size_t copied = 0;
Expand All @@ -99,8 +97,6 @@ static int vrr_recvmsg(struct kiocb *iocb, struct socket *sock,
if (err)
goto done;

// sock_recv_ts_and_drops(msg, sk, skb);

if (svrr) {
svrr->svrr_family = AF_VRR;
svrr->svrr_addr = vrr_hdr(skb)->dest_id;
Expand All @@ -124,93 +120,102 @@ void vrr_destroy_sock(struct sock *sk)
}
}

static int vrr_release(struct socket *sock)
{
struct sock *sk = sock->sk;

if (sk) {
sock_orphan(sk);
sock_hold(sk);
sock_put(sk);
}

return 0;
}

static int vrr_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len)
{
// int addr_len = msg->msg_namelen;
int err = 0;
size_t sent = 0;
struct sk_buff *skb = NULL;
struct sock *sk = sock->sk;
struct sockaddr_vrr *addr = (struct sockaddr_vrr *)msg->msg_name;
struct sockaddr_vrr *dest = (struct sockaddr_vrr *)msg->msg_name;
struct vrr_packet pkt;
// struct vrr_sock *vrr = vrr_sk(sk);
u32 nh;
struct vrr_node *me = vrr_get_node();
size_t sent = 0;
int ret = -EINVAL;

if (unlikely(!dest))
return -EDESTADDRREQ;

WARN_ATOMIC;
if (dest->svrr_addr != me->id) {
nh = rt_get_next(dest->svrr_addr);
if (!nh)
return -EHOSTUNREACH;

if (sk->sk_shutdown & SEND_SHUTDOWN) {
return -EPIPE;
if (!pset_get_mac(nh, pkt.dest_mac))
return -EHOSTUNREACH;
}

err = -ENOBUFS;
if (iocb)
lock_sock(sk);

pkt.src = get_vrr_id();
pkt.dst = addr->svrr_addr;
pkt.dst = dest->svrr_addr;
pkt.pkt_type = VRR_DATA;
VRR_ERR("pkt members initialized.");
pkt.data_len = len;

/* Allocate an skb for sending */
skb = vrr_skb_alloc(len + VRR_MAX_HEADER, GFP_KERNEL);
skb = vrr_skb_alloc(len, GFP_KERNEL);
if (!skb) {
VRR_ERR("vrr_skb_alloc failed");
goto out_err;
}
VRR_ERR("vrr_skb_alloc succeeded.");

/* Build the vrr header */
err = build_header(skb, &pkt);
if (err) {
VRR_ERR("build_header failed");
ret = build_header(skb, &pkt);
if (ret)
goto out_err;
}
VRR_ERR("build_header succeeded.");

/* Copy data from userspace */
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
VRR_ERR("memcpy_fromiovec failed");
err = -EFAULT;
ret = -EFAULT;
goto out;
}
VRR_ERR("memcpy_fromiovec succeeded.");

sent += len;

/* Send packet */
vrr_output(skb, vrr_get_node(), VRR_DATA);
goto out;
vrr_output(skb, me, VRR_DATA);

out_err:
kfree_skb(skb);
out:
return sent ? sent : err;
if (iocb)
release_sock(sk);
return sent ? sent : ret;
}

static void vrr_sock_destruct(struct sock *sk)
static int vrr_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
__skb_queue_purge(&sk->sk_receive_queue);
__skb_queue_purge(&sk->sk_error_queue);
return 0;
}

sk_mem_reclaim(sk);
static int vrr_release(struct socket *sock)
{
struct sock *sk = sock->sk;
struct sk_buff *skb;

if (sk == NULL)
return 0;

lock_sock(sk);

while ((skb = __skb_dequeue(&sk->sk_receive_queue)))
kfree_skb(skb);

sock->state = SS_UNCONNECTED;
release_sock(sk);

sock_put(sk);
sock->sk = NULL;

return 0;
}

struct proto vrr_proto = {
.name = "VRR",
.owner = THIS_MODULE,
.max_header = VRR_MAX_HEADER,
.obj_size = sizeof(struct vrr_sock),
.obj_size = sizeof(struct sock),
};

static struct proto_ops vrr_proto_ops = {
Expand All @@ -235,36 +240,36 @@ static struct proto_ops vrr_proto_ops = {
};

static int vrr_create(struct net *net, struct socket *sock,
int protocol, int kern)
int protocol)
{
struct sock *sk;
struct vrr_sock *vrr;
int err;

VRR_INFO("Begin vrr_create");
VRR_DBG("proto: %u", protocol);

err = -ENOBUFS;
if (unlikely(protocol != 0))
return -EPROTONOSUPPORT;

if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;

sk = sk_alloc(net, PF_VRR, GFP_KERNEL, &vrr_proto);
if (!sk)
goto out;
if (sk == NULL)
return -ENOMEM;

err = 0;
vrr = vrr_sk(sk);
sock->ops = &vrr_proto_ops;
sock->state = SS_CONNECTING;

if (sock) {
sock->ops = &vrr_proto_ops;
}
sock_init_data(sock, sk);

sk->sk_destruct = vrr_sock_destruct;
sk->sk_rcvtimeo = msecs_to_jiffies(VRR_FAIL_TIMEOUT * VRR_HPKT_DELAY);
sk->sk_backlog_rcv = vrr_backlog_rcv;
sk->sk_family = PF_VRR;
sk->sk_protocol = protocol;
sk->sk_allocation = GFP_KERNEL;

VRR_INFO("End vrr_create");
out:
return err;

return 0;
}

const struct net_proto_family vrr_family_ops = {
Expand Down
10 changes: 2 additions & 8 deletions vrr.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,21 +134,15 @@ struct vrr_packet {
mac_addr dest_mac;
};

struct vrr_sock {
struct sock *sk;
u_int src_addr;
u_int dest_addr;
};

struct vrr_header {
u8 vrr_version;
u8 pkt_type;
u16 protocol;
u16 data_len;
u8 free;
u16 h_csum;
u_int src_id;
u_int dest_id;
u32 src_id;
u32 dest_id;
u8 dest_mac[6];
};

Expand Down
3 changes: 0 additions & 3 deletions vrr_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,8 @@ int vrr_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,

WARN_ATOMIC;

/* Do stuff! */
printk(KERN_ALERT "Received a VRR packet!");
/* skb->pkt_type should be ETH_P_VRR */

/* Debug vrr header */
VRR_INFO("vrr_version: %x", vh->vrr_version);
VRR_INFO("pkt_type: %x", vh->pkt_type);
VRR_INFO("protocol: %x", ntohs(vh->protocol));
Expand Down
48 changes: 18 additions & 30 deletions vrr_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,40 @@ int vrr_output(struct sk_buff *skb, struct vrr_node *vrr,
int type)
{
struct net_device *dev;
struct ethhdr header;
struct vrr_header *vh;
int err = 0;
struct sk_buff *clone;

WARN_ATOMIC;

VRR_DBG("Output started");

vh = (struct vrr_header *)skb->data;

VRR_INFO("vrr_version: %x", vh->vrr_version);
VRR_INFO("pkt_type: %x", vh->pkt_type);
VRR_INFO("protocol: %x", ntohs(vh->protocol));
VRR_INFO("data_len: %x", ntohs(vh->data_len));
VRR_INFO("free: %x", vh->free);
VRR_INFO("h_csum: %x", vh->h_csum);
VRR_INFO("src_id: %x", ntohl(vh->src_id));
VRR_INFO("dest_id: %x", ntohl(vh->dest_id));

dev = dev_get_by_name(&init_net, vrr->dev_name);
if (dev == 0) {
VRR_ERR("Device %s does not exist", vrr->dev_name);
err = -1;
goto out;
return -1;
}
skb->dev = dev;

if (type == VRR_HELLO)
memcpy(&header.h_dest, dev->broadcast, MAC_ADDR_LEN);
else
memcpy(&header.h_dest, vh->dest_mac, MAC_ADDR_LEN);

memcpy(&header.h_source, dev->dev_addr, MAC_ADDR_LEN);
header.h_proto = htons(ETH_P_VRR);

memcpy(skb_push(skb, sizeof(header)), &header, sizeof(header));

/* Check destination for local delivery */
if (!memcmp(dev->dev_addr, vh->dest_mac, ETH_ALEN)) {
VRR_DBG("Delivering locally");
skb_set_mac_header(skb, 0);
skb_set_network_header(skb, sizeof(struct ethhdr));
vrr_rcv(skb, dev, NULL, NULL);
goto out_success;
clone = skb_clone(skb, GFP_ATOMIC);
if (clone) {
skb_reset_network_header(clone);
clone->dev = dev;
dev_hard_header(clone, dev, ETH_P_VRR, vh->dest_mac,
dev->dev_addr, clone->len);
dev_queue_xmit(clone);
}

dev_queue_xmit(skb);

VRR_DBG("Output done");

out_success:
return NET_XMIT_SUCCESS;

out:
return err;
}

/* Call the routing table to find next hop destination */
Expand Down

0 comments on commit a80c0ab

Please sign in to comment.