Hi,
I am asked to run a real-time networking application on a non real-time
network, so, I naturally thought about using RTnet.
But unless I am completely mistaken, it is not what RTnet is originally
made for. As far as I understood, in an RTnet network, the non real-time
trafic is tunneled through the real-time traffic by adding an rtmac
header with the RTMAC_FLAG_TUNNEL flag set. But since the other nodes on
the network I am on are non-rt, they do not understand the rtmac header.
So, I started hacking RTnet to get what I wanted, and since I believe it
may interest other users, I submit the patch here. I do not expect this
patch to be integrated as is, it is merely a one day hack, but it should
demonstrate my use-case of RTnet and hopefully influence RTnet
developers to take this use-case into account.
Regards.
--
Gilles Chanteperdrix
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/include/ipv4/protocol.h rtnet/stack/include/ipv4/protocol.h
--- rtnet-0.9.8/stack/include/ipv4/protocol.h 2006-08-07 10:15:51.000000000 +0200
+++ rtnet/stack/include/ipv4/protocol.h 2007-03-14 18:58:44.000000000 +0100
@@ -40,7 +40,7 @@ struct rtinet_protocol {
unsigned short protocol;
struct rtsocket *(*dest_socket)(struct rtskb *);
- void (*rcv_handler)(struct rtskb *);
+ int (*rcv_handler)(struct rtskb *);
void (*err_handler)(struct rtskb *);
int (*init_socket)(struct rtdm_dev_context *,
rtdm_user_info_t *);
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/include/rtmac/rtmac_proto.h rtnet/stack/include/rtmac/rtmac_proto.h
--- rtnet-0.9.8/stack/include/rtmac/rtmac_proto.h 2005-02-28 12:27:33.000000000 +0100
+++ rtnet/stack/include/rtmac/rtmac_proto.h 2007-03-15 12:05:52.000000000 +0100
@@ -34,17 +34,20 @@
#define RTMAC_FLAG_TUNNEL 0x01
+#ifdef CONFIG_RTMAC_HDR
struct rtmac_hdr {
u16 type;
u8 ver;
u8 flags;
} __attribute__ ((packed));
+#endif /* CONFIG_RTMAC_HDR */
static inline int rtmac_add_header(struct rtnet_device *rtdev, void *daddr,
struct rtskb *skb, u16 type, u8 flags)
{
+#ifdef CONFIG_RTMAC_HDR
struct rtmac_hdr *hdr =
(struct rtmac_hdr *)rtskb_push(skb, sizeof(struct rtmac_hdr));
@@ -59,6 +62,14 @@ static inline int rtmac_add_header(struc
(rtdev->hard_header(skb, rtdev, ETH_RTMAC, daddr,
rtdev->dev_addr, skb->len) < 0))
return -1;
+#else
+ skb->rtdev = rtdev;
+
+ if (rtdev->hard_header &&
+ (rtdev->hard_header(skb, rtdev, type, daddr,
+ rtdev->dev_addr, skb->len) < 0))
+ return -1;
+#endif
return 0;
}
@@ -81,7 +92,11 @@ static inline int rtmac_xmit(struct rtsk
extern struct rtpacket_type rtmac_packet_type;
+#ifdef CONFIG_RTMAC_HDR
#define rtmac_proto_init() rtdev_add_pack(&rtmac_packet_type)
+#else
+int rtmac_proto_init(void);
+#endif
void rtmac_proto_release(void);
#endif /* __RTMAC_PROTO_H_ */
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/ipv4/arp.c rtnet/stack/ipv4/arp.c
--- rtnet-0.9.8/stack/ipv4/arp.c 2006-09-15 13:25:01.000000000 +0200
+++ rtnet/stack/ipv4/arp.c 2007-03-15 11:19:31.000000000 +0100
@@ -168,14 +168,23 @@ int rt_arp_rcv(struct rtskb *skb, struct
if (tip == rtdev->local_ip) {
rt_ip_route_add_host(sip, sha, rtdev);
- if (arp->ar_op == __constant_htons(ARPOP_REQUEST))
- rt_arp_send(ARPOP_REPLY, ETH_P_ARP, sip, rtdev, tip, sha,
- rtdev->dev_addr, sha);
+ if (arp->ar_op == __constant_htons(ARPOP_REQUEST)) {
+ rt_arp_send(ARPOP_REPLY, ETH_P_ARP, sip, rtdev, tip, sha,
+ rtdev->dev_addr, sha);
+#ifndef CONFIG_RTMAC_HDR
+ kfree_rtskb(skb);
+ return 0;
+#endif
+ }
}
out:
+#ifdef CONFIG_RTMAC_HDR
kfree_rtskb(skb);
return 0;
+#else
+ return 1;
+#endif
}
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/ipv4/icmp.c rtnet/stack/ipv4/icmp.c
--- rtnet-0.9.8/stack/ipv4/icmp.c 2006-09-04 19:15:15.000000000 +0200
+++ rtnet/stack/ipv4/icmp.c 2007-03-15 11:17:35.000000000 +0100
@@ -62,7 +62,7 @@ struct icmp_bxm
struct rt_icmp_control
{
- void (*handler)(struct rtskb *skb);
+ int (*handler)(struct rtskb *skb);
short error; /* This ICMP is classed as an error message */
};
@@ -132,8 +132,14 @@ void rt_icmp_cleanup_echo_requests(void)
/***
* rt_icmp_discard - dummy function
*/
-static void rt_icmp_discard(struct rtskb *skb)
+static int rt_icmp_discard(struct rtskb *skb)
{
+#ifdef CONFIG_RTMAC_HDR
+ kfree_rtskb(skb);
+ return 0;
+#else
+ return 1;
+#endif
}
@@ -200,7 +206,7 @@ static void rt_icmp_send_reply(struct ic
/***
* rt_icmp_echo - handles echo replies on our previously sent requests
*/
-static void rt_icmp_echo_reply(struct rtskb *skb)
+static int rt_icmp_echo_reply(struct rtskb *skb)
{
rtdm_lockctx_t context;
struct rt_proc_call *call;
@@ -216,7 +222,12 @@ static void rt_icmp_echo_reply(struct rt
rtdm_lock_put_irqrestore(&echo_calls_lock, context);
} else {
rtdm_lock_put_irqrestore(&echo_calls_lock, context);
- return;
+#ifdef CONFIG_RTMAC_HDR
+ kfree_rtskb(skb);
+ return 0;
+#else
+ return 1;
+#endif
}
cmd = rtpc_get_priv(call, struct ipv4_cmd);
@@ -233,6 +244,13 @@ static void rt_icmp_echo_reply(struct rt
rtpc_complete_call(call, sizeof(struct icmphdr) + skb->len);
} else
rtpc_complete_call(call, 0);
+
+#ifdef CONFIG_RTMAC_HDR
+ kfree_rtskb(skb);
+ return 0;
+#else
+ return 1;
+#endif
}
@@ -240,7 +258,7 @@ static void rt_icmp_echo_reply(struct rt
/***
* rt_icmp_echo_request - handles echo requests sent by other stations
*/
-static void rt_icmp_echo_request(struct rtskb *skb)
+static int rt_icmp_echo_request(struct rtskb *skb)
{
struct icmp_bxm icmp_param;
@@ -253,8 +271,9 @@ static void rt_icmp_echo_request(struct
icmp_param.head_len = sizeof(struct icmphdr);
rt_icmp_send_reply(&icmp_param, skb);
+ kfree_rtskb(skb);
- return;
+ return 0;
}
@@ -439,7 +458,7 @@ struct rtsocket *rt_icmp_dest_socket(str
/***
* rt_icmp_rcv
*/
-void rt_icmp_rcv(struct rtskb *skb)
+int rt_icmp_rcv(struct rtskb *skb)
{
struct icmphdr *icmpHdr = skb->h.icmph;
unsigned int length = skb->len;
@@ -472,10 +491,15 @@ void rt_icmp_rcv(struct rtskb *skb)
}
/* sane packet, process it */
- rt_icmp_pointers[icmpHdr->type].handler(skb);
+ return rt_icmp_pointers[icmpHdr->type].handler(skb);
cleanup:
+#ifdef CONFIG_RTMAC_HDR
kfree_rtskb(skb);
+ return 0;
+#else
+ return 1;
+#endif
}
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/ipv4/ip_input.c rtnet/stack/ipv4/ip_input.c
--- rtnet-0.9.8/stack/ipv4/ip_input.c 2006-08-07 10:15:51.000000000 +0200
+++ rtnet/stack/ipv4/ip_input.c 2007-03-15 10:44:45.000000000 +0100
@@ -43,7 +43,7 @@ EXPORT_SYMBOL(rt_ip_fallback_handler);
/***
* rt_ip_local_deliver
*/
-static inline void rt_ip_local_deliver(struct rtskb *skb)
+static inline int rt_ip_local_deliver(struct rtskb *skb)
{
struct iphdr *iph = skb->nh.iph;
unsigned short protocol = iph->protocol;
@@ -66,12 +66,15 @@ static inline void rt_ip_local_deliver(s
if (iph->frag_off & htons(IP_MF|IP_OFFSET)) {
skb = rt_ip_defrag(skb, ipprot);
if (!skb)
- return;
+ return 1;
} else {
/* Get the destination socket */
if ((sock = ipprot->dest_socket(skb)) == NULL) {
+#ifdef CONFIG_RTMAC_HDR
kfree_rtskb(skb);
- return;
+ return 0;
+#endif
+ return 1;
}
/* Acquire the rtskb at the expense of the protocol pool */
@@ -81,13 +84,16 @@ static inline void rt_ip_local_deliver(s
rt_socket_dereference(sock);
if (err) {
+#ifdef CONFIG_RTMAC_HDR
kfree_rtskb(skb);
- return;
+ return 0;
+#endif
+ return 1;
}
}
/* Deliver the packet to the next layer */
- ipprot->rcv_handler(skb);
+ return ipprot->rcv_handler(skb);
#ifdef CONFIG_RTNET_ADDON_PROXY
} else if (rt_ip_fallback_handler) {
/* If a fallback handler for IP protocol has been installed,
@@ -96,7 +102,11 @@ static inline void rt_ip_local_deliver(s
#endif /* CONFIG_RTNET_ADDON_PROXY */
} else {
rtdm_printk("RTnet: no protocol found\n");
+#ifdef CONFIG_RTMAC_HDR
kfree_rtskb(skb);
+ return 0;
+#endif
+ return 1;
}
}
@@ -145,8 +155,7 @@ int rt_ip_rcv(struct rtskb *skb, struct
return 0;
#endif /* CONFIG_RTNET_RTIPV4_ROUTER */
- rt_ip_local_deliver(skb);
- return 0;
+ return rt_ip_local_deliver(skb);
drop:
kfree_rtskb(skb);
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/ipv4/udp.c rtnet/stack/ipv4/udp.c
--- rtnet-0.9.8/stack/ipv4/udp.c 2006-12-11 17:29:52.000000000 +0100
+++ rtnet/stack/ipv4/udp.c 2007-03-14 19:01:30.000000000 +0100
@@ -723,7 +723,7 @@ struct rtsocket *rt_udp_dest_socket(stru
/***
* rt_udp_rcv
*/
-void rt_udp_rcv (struct rtskb *skb)
+int rt_udp_rcv (struct rtskb *skb)
{
struct rtsocket *sock = skb->sk;
void (*callback_func)(struct rtdm_dev_context *, void *);
@@ -746,6 +746,7 @@ void rt_udp_rcv (struct rtskb *skb)
if (callback_func)
callback_func(rt_socket_context(sock), callback_arg);
+ return 0;
}
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/rtmac/rtmac_proto.c rtnet/stack/rtmac/rtmac_proto.c
--- rtnet-0.9.8/stack/rtmac/rtmac_proto.c 2006-09-15 13:27:24.000000000 +0200
+++ rtnet/stack/rtmac/rtmac_proto.c 2007-03-15 12:06:24.000000000 +0100
@@ -31,6 +31,7 @@
+#ifdef CONFIG_RTMAC_HDR
int rtmac_proto_rx(struct rtskb *skb, struct rtpacket_type *pt)
{
struct rtmac_disc *disc = skb->rtdev->mac_disc;
@@ -82,3 +83,55 @@ void rtmac_proto_release(void)
schedule_timeout(1*HZ); /* wait a second */
}
}
+#else /* !CONFIG_RTMAC_HDR */
+static int forward_to_vnic(struct rtskb *skb, struct rtpacket_type *pt)
+{
+ rtmac_vnic_rx(skb, skb->protocol);
+ return 0;
+}
+
+static struct rtpacket_type vnic_arp_packet_type = {
+ type: __constant_htons(ETH_P_ARP),
+ handler: forward_to_vnic
+};
+
+static struct rtpacket_type vnic_ip_packet_type = {
+ type: __constant_htons(ETH_P_IP),
+ handler: forward_to_vnic
+};
+
+int rtmac_proto_init(void)
+{
+ extern void rt_ip_init(void);
+ void *ptr = (void *) &rt_ip_init; /* Reference the rtipv4 module so that
+ * it must be loaded before this one.*/
+ int rc = rtdev_add_pack(&vnic_arp_packet_type);
+ if (rc)
+ return rc;
+
+ rc = rtdev_add_pack(&vnic_ip_packet_type);
+ if (rc) {
+ while (rtdev_remove_pack(&vnic_arp_packet_type) == -EAGAIN) {
+ rtdm_printk("RTmac: waiting for protocol unregistration\n");
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1*HZ); /* wait a second */
+ }
+ }
+
+ return rc;
+}
+
+void rtmac_proto_release(void)
+{
+ while (rtdev_remove_pack(&vnic_arp_packet_type) == -EAGAIN) {
+ rtdm_printk("RTmac: waiting for protocol unregistration\n");
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1*HZ); /* wait a second */
+ }
+ while (rtdev_remove_pack(&vnic_ip_packet_type) == -EAGAIN) {
+ rtdm_printk("RTmac: waiting for protocol unregistration\n");
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1*HZ); /* wait a second */
+ }
+}
+#endif /* !CONFIG_RTMAC_HDR */
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/rtmac/rtmac_vnic.c rtnet/stack/rtmac/rtmac_vnic.c
--- rtnet-0.9.8/stack/rtmac/rtmac_vnic.c 2006-08-07 10:15:51.000000000 +0200
+++ rtnet/stack/rtmac/rtmac_vnic.c 2007-03-15 11:54:14.000000000 +0100
@@ -93,6 +93,7 @@ static void rtmac_vnic_signal_handler(rt
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
+#ifdef CONFIG_RTMAC_HDR
/* copy Ethernet header */
memcpy(skb_put(skb, hdrlen),
rtskb->data - hdrlen - sizeof(struct rtmac_hdr), hdrlen);
@@ -102,6 +103,10 @@ static void rtmac_vnic_signal_handler(rt
/* copy data */
memcpy(skb_put(skb, rtskb->len), rtskb->data, rtskb->len);
+#else
+ memcpy(skb_put(skb, hdrlen + rtskb->len),
+ rtskb->data - hdrlen, hdrlen + rtskb->len);
+#endif
skb->dev = &rtskb->rtdev->mac_priv->vnic;
skb->protocol = eth_type_trans(skb, skb->dev);
@@ -147,14 +152,23 @@ int rtmac_vnic_xmit(struct sk_buff *skb,
int data_len;
+#ifdef CONFIG_RTMAC_HDR
rtskb =
alloc_rtskb((skb->len + sizeof(struct rtmac_hdr) + 15) & ~15, pool);
+#else
+ rtskb =
+ alloc_rtskb((skb->len + 15) & ~15, pool);
+#endif
if (!rtskb) {
stats->tx_dropped++;
return -ENOMEM;
}
+#ifdef CONFIG_RTMAC_HDR
rtskb_reserve(rtskb, rtdev->hard_header_len + sizeof(struct rtmac_hdr));
+#else
+ rtskb_reserve(rtskb, rtdev->hard_header_len);
+#endif
data_len = skb->len - dev->hard_header_len;
memcpy(rtskb_put(rtskb, data_len), skb->data + dev->hard_header_len,
@@ -195,9 +209,14 @@ static struct net_device_stats *rtmac_vn
static int rtmac_vnic_change_mtu(struct net_device *dev, int new_mtu)
{
+#ifdef CONFIG_RTMAC_HDR
if ((new_mtu < 68) ||
((unsigned)new_mtu > 1500 - sizeof(struct rtmac_hdr)))
return -EINVAL;
+#else
+ if ((new_mtu < 68) || ((unsigned)new_mtu > 1500))
+ return -EINVAL;
+#endif
dev->mtu = new_mtu;
return 0;
}
@@ -210,7 +229,11 @@ void rtmac_vnic_set_max_mtu(struct rtnet
unsigned int prev_mtu = mac_priv->vnic_max_mtu;
+#ifdef CONFIG_RTMAC_HDR
mac_priv->vnic_max_mtu = max_mtu - sizeof(struct rtmac_hdr);
+#else
+ mac_priv->vnic_max_mtu = max_mtu;
+#endif
/* set vnic mtu in case max_mtu is smaller than the current mtu or
the current mtu was set to previous max_mtu */
@@ -266,7 +289,11 @@ int rtmac_vnic_add(struct rtnet_device *
return 0;
mac_priv->vnic_registered = 0;
+#ifdef CONFIG_RTMAC_HDR
mac_priv->vnic_max_mtu = rtdev->mtu - sizeof(struct rtmac_hdr);
+#else
+ mac_priv->vnic_max_mtu = rtdev->mtu;
+#endif
memset(&mac_priv->vnic_stats, 0, sizeof(mac_priv->vnic_stats));
/* create the rtskb pool */
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/stack_mgr.c rtnet/stack/stack_mgr.c
--- rtnet-0.9.8/stack/stack_mgr.c 2006-09-15 16:10:18.000000000 +0200
+++ rtnet/stack/stack_mgr.c 2007-03-15 10:43:17.000000000 +0100
@@ -173,6 +173,10 @@ __DELIVER_PREFIX void rt_stack_deliver(s
list_for_each_entry(pt_entry, &rt_packets[hash], list_entry)
if (pt_entry->type == rtskb->protocol) {
+#ifndef CONFIG_RTMAC_HDR
+ unsigned char *data = rtskb->data;
+ unsigned len = rtskb->len;
+#endif
pt_entry->refcount++;
rtdm_lock_put_irqrestore(&rt_packets_lock, context);
@@ -187,6 +191,12 @@ __DELIVER_PREFIX void rt_stack_deliver(s
rtdm_lock_put_irqrestore(&rt_packets_lock, context);
return;
}
+#ifndef CONFIG_RTMAC_HDR
+ /* Discard any progress made by the last callback before passing the
+ packet to the next callback. */
+ rtskb->data = data;
+ rtskb->len = len;
+#endif
}
rtdm_lock_put_irqrestore(&rt_packets_lock, context);
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
RTnet-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rtnet-developers