한 메모리 영역에 동시에 접근하는 문제...

cjy1126의 이미지

제가 만들고 있는 swtich에 NIDS가 3개 붙어있습니다

라운드로빈같은 스켈쥴링 기법을 이용하여 NIDS에 패킷을 흘려보내는데, 같은 source ip에서 온 패킷은 계속 같은 곳으로 보내기위해서 테이블을 만들었습니다.(패킷분할공격대비용)

struct packet
{
   struct list_head hash_list;
   u32 source;
   u32 dest;
   struct timer_list timer;
   struct net_device *dev;
}

버킷의수가 4096개인 해쉬테이블을 만들어서 패킷이 올때마다 source ip와 dest ip로 해쉬값을 뽑아 그 패킷에대한 리스트가 있는지 search하고 있으면 그 패킷이 나갔던 *dev를 반환하고, 없으면packet 구조체형 링크드 리스트로 연결합니다.

오랬동안 사용안하는 리스트를 지우기위해서 add될때는 add_timer를 호출해서 (jiffies+60*HZ)을 timer의 expires로 설정하고, 호출함수는 delete_node를 호출합니다.

모듈로 테스트해봐서 여기까지는 잘 작동합니다.

문제는 실제 커널에 심었을때 expires가 지나면 delete_node를 호출하는데, 커널 패닉이 일어납니다.

제 생각으로는 네트웍 카드로 패킷은 계속 들어오는데, 60초가 지난 패킷이 지워짐과 동시에 들어오는것 같습니다.

즉... 같은 링크드 리스트의 구조체를 동시에 읽고 쓰는것 같습니다.

이 문제를 어떻게 해결해야하나요?

ipvs에 write_lock를 써도... 조금 더 버틸뿐이고... 결국은 커널패닉이 일어나네요.

bblackstar의 이미지

Quote:
문제는 실제 커널에 심었을때 expires가 지나면 delete_node를 호출하는데, 커널 패닉이 일어납니다.

제 생각으로는 네트웍 카드로 패킷은 계속 들어오는데, 60초가 지난 패킷이 지워짐과 동시에 들어오는것 같습니다.

즉... 같은 링크드 리스트의 구조체를 동시에 읽고 쓰는것 같습니다.

만일 문제가 delete_node() 에서 발생하는 것이 맞다면,
그리고 지우려는 노드를 사용하려는 패킷이 접근을 하다가 panic이 발생하는
것이라면, 앞 부분에 버퍼를 두고 그곳에서 packet 노드를 접근하기 전에
그 노드가 존재하는지에 대한 체크를 하는 루틴을 넣어 보시는 것은 어떨까요?
존재하지 않는다면 그 버퍼에서 drop을 시켜 주는 방식이지요.

패킷처리루틴에 그렇게 많은 overhead를 줄거 같지는 않을거 같습니다. ^^

whiterock의 이미지

이미 해제된 메모리에 접근을 하게 되는게 아닌지..참조 방식으로 고쳐 보시는건 어떠 실런지요..

리스트에 들어가는 데이터들에게 참조 카운터를 넣으셔서, 그 데이터를 사용하기 전에 참조 카운터를 증가 시키시고 사용 후에는 참조 카운터를 감소 시키주고, 참조 카운터가 0이 되면 메모리 반납을 해주는..그런 방식이요.

흐음...

cjy1126의 이미지

문제는 kmalloc였네요.

처음에 해쉬 테이블을 만들때는 kmalloc로 할당하는게 맞는데, 패킷이 올때마다 할당받는 메모리는 작은 용량이라서 kmalloc로 할당하면 안된다더군요.

집에서 샤워하고 오는동안 같이 프로젝트하는분이 해결해놓으셨네요.

최종호의 이미지

cjy1126 wrote:
문제는 kmalloc였네요.

처음에 해쉬 테이블을 만들때는 kmalloc로 할당하는게 맞는데, 패킷이 올때마다 할당받는 메모리는 작은 용량이라서 kmalloc로 할당하면 안된다더군요.

집에서 샤워하고 오는동안 같이 프로젝트하는분이 해결해놓으셨네요.

그럼 조그만 메모리를 관리하는 메모리관리자를 사용자가 작성해야 하는건가요? 어떻게 해결하셨는지 궁금.. ^^

cjy1126의 이미지

kmem_cache_create
kmem_cache_alloc
kmem_cache_free
kmem_cache_destroy

를 사용했습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.