R&D/VRouter

KVM UDP 패치

sunshout 2009. 4. 9. 14:48

qemu에서 수정코드 (Language : c)
+typedef struct UDPState {
+  VLANClientState *vc;
int fd;
struct sockaddr_in sender;
+} UDPState;
+
+static void net_udp_send (void *opaque)
+{
+  UDPState *s = opaque;
+  uint8_t buf[4096];
int size;
+  size = recvfrom(s->fd, buf, sizeof(buf), 0, NULL, NULL);
+
if (size > 0)
+    qemu_send_packet(s->vc, buf, size);
+}
+
+static void net_udp_receive(void *opaque, const uint8_t *buf, int size)
+{
+  UDPState *s = opaque;
int res;
+  res = sendto(s->fd, buf, size, 0, (struct sockaddr *)&s->sender,
sizeof (s->sender));
+}
+
+static int net_udp_init(VLANState *vlan, int lport, char *rhost, int rport)
+{
+  UDPState *s;
struct sockaddr_in reciever;
int ret;
+
+  s = qemu_mallocz(sizeof(DUDPState));
if (!s)
+    return -1;
+
+  s->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
if (s->fd < 0) {
+    perror("socket")
+    return -1;
}
+
+  reciever.sin_family = AF_INET;
+  reciever.sin_addr.s_addr = INADDR_ANY;
+  reciever.sin_port = htons(lport);
+
+  ret = bind(s->rfd, (struct sockaddr *)&reciever, sizeof(reciever))
if (ret < 0) {
+    perror("bind");
+    return -1;
}
+
+  memset((char*)&s->sender, sizeof(s->sender), 0);
+  s->sender.sin_family = AF_INET;
+  s->sender.sin_port = htons(rport);
+  inet_aton(rhost, &s->sender.sin_addr);
+
+  s->vc = qemu_new_vlan_client(vlan, net_udp_receive, NULL, s);
+  qemu_set_fd_handler(s->rfd, net_udp_send, NULL, s);
+
+  snprintf(s->vc->info_str, sizeof(s->vc->info_str),
+      "udp: %i->%s:%i",
+      lport, rhost, rport);
+
return 0;
+}
+
static const char *get_opt_name(char *buf, int buf_size, const char *p)
{
     char *q;
@@ -5313,6 +5379,26 @@
        ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode);
     } else
#endif
+    if (!strcmp(device, "udp")) {
+        int sport, dport;
+        char buf[128];
+
+        if (get_param_value(buf, sizeof(buf), "dport", p) <= 0) {
+          fprintf(stderr, "You must specify a destination port with dport\n");
+          exit(0);
+        }
+        dport = atoi(buf);
+        if (get_param_value(buf, sizeof(buf), "sport", p)<=0) {
+          fprintf(stderr, "You must specify a source port with sport\n");
+          exit(0);
+        }
+        sport = atoi(buf);
+        if (get_param_value(buf, sizeof(buf), "daddr", p) <= 0) {
+          fprintf(stderr, "You must specify a destination address
with daddr\n"
);
+          exit(0);
+        }
+       ret = net_dudp_init(vlan,sport,daddr,dport);
+    } else
     {
         fprintf(stderr, "Unknown network device: %s\n", device);
         return -1;
@@ -8225,6 +8311,8 @@
            "                Use group 'groupname' and mode
'octalmode' to change default\n"

            "                ownership and permissions for
communication port.\n"

#endif
+           "-net udp[,vlan=n]sport=sport,dport=dport,daddr=host\n"
+           "                connect the vlan 'n' to a udp host (for
dynamips)\n"

            "-net none       use it alone to have zero network
devices; if no -net option\n"

            "                is provided, the default is '-net nic -net user'\n"
            "\n"

qemu의 수정코드인데 -net udp를 하게 만들었다. 이렇게 만들어도 되고 지금 KVM에 존재하는 socket 코드안에 수정하는 방법도 있을거 같다.