linux/arch/um/drivers/mcast_kern.c
<<
>>
Prefs
   1/*
   2 * user-mode-linux networking multicast transport
   3 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
   4 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
   5 *
   6 * based on the existing uml-networking code, which is
   7 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
   8 * James Leu (jleu@mindspring.net).
   9 * Copyright (C) 2001 by various other people who didn't put their name here.
  10 *
  11 * Licensed under the GPL.
  12 */
  13
  14#include "linux/init.h"
  15#include <linux/netdevice.h>
  16#include "mcast.h"
  17#include "net_kern.h"
  18
  19struct mcast_init {
  20        char *addr;
  21        int port;
  22        int ttl;
  23};
  24
  25static void mcast_init(struct net_device *dev, void *data)
  26{
  27        struct uml_net_private *pri;
  28        struct mcast_data *dpri;
  29        struct mcast_init *init = data;
  30
  31        pri = netdev_priv(dev);
  32        dpri = (struct mcast_data *) pri->user;
  33        dpri->addr = init->addr;
  34        dpri->port = init->port;
  35        dpri->ttl = init->ttl;
  36        dpri->dev = dev;
  37
  38        printk("mcast backend multicast address: %s:%u, TTL:%u\n",
  39               dpri->addr, dpri->port, dpri->ttl);
  40}
  41
  42static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
  43{
  44        return net_recvfrom(fd, skb_mac_header(skb),
  45                            skb->dev->mtu + ETH_HEADER_OTHER);
  46}
  47
  48static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
  49{
  50        return mcast_user_write(fd, skb->data, skb->len,
  51                                (struct mcast_data *) &lp->user);
  52}
  53
  54static const struct net_kern_info mcast_kern_info = {
  55        .init                   = mcast_init,
  56        .protocol               = eth_protocol,
  57        .read                   = mcast_read,
  58        .write                  = mcast_write,
  59};
  60
  61static int mcast_setup(char *str, char **mac_out, void *data)
  62{
  63        struct mcast_init *init = data;
  64        char *port_str = NULL, *ttl_str = NULL, *remain;
  65        char *last;
  66
  67        *init = ((struct mcast_init)
  68                { .addr         = "239.192.168.1",
  69                  .port         = 1102,
  70                  .ttl          = 1 });
  71
  72        remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
  73                               NULL);
  74        if (remain != NULL) {
  75                printk(KERN_ERR "mcast_setup - Extra garbage on "
  76                       "specification : '%s'\n", remain);
  77                return 0;
  78        }
  79
  80        if (port_str != NULL) {
  81                init->port = simple_strtoul(port_str, &last, 10);
  82                if ((*last != '\0') || (last == port_str)) {
  83                        printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
  84                               port_str);
  85                        return 0;
  86                }
  87        }
  88
  89        if (ttl_str != NULL) {
  90                init->ttl = simple_strtoul(ttl_str, &last, 10);
  91                if ((*last != '\0') || (last == ttl_str)) {
  92                        printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
  93                               ttl_str);
  94                        return 0;
  95                }
  96        }
  97
  98        printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
  99               init->port, init->ttl);
 100
 101        return 1;
 102}
 103
 104static struct transport mcast_transport = {
 105        .list           = LIST_HEAD_INIT(mcast_transport.list),
 106        .name           = "mcast",
 107        .setup          = mcast_setup,
 108        .user           = &mcast_user_info,
 109        .kern           = &mcast_kern_info,
 110        .private_size   = sizeof(struct mcast_data),
 111        .setup_size     = sizeof(struct mcast_init),
 112};
 113
 114static int register_mcast(void)
 115{
 116        register_transport(&mcast_transport);
 117        return 0;
 118}
 119
 120late_initcall(register_mcast);
 121